function _(str) { /* getText */
	if (!(str in window.LOCALE)) { return str; }
	return window.LOCALE[str];
}

var DATATYPES = $.parseXML('<datatypes db="mysql">\
	<group label="Numeric" color="rgb(238,238,170)">\
	 	<type label="TINYINT" length="0" sql="TINYINT" quote="" />\
	 	<type label="SMALLINT" length="0" sql="SMALLINT" quote="" />\
	 	<type label="MEDIUMINT" length="0" sql="MEDIUMINT" quote="" />\
	 	<type label="INT" length="0" sql="INT" quote="" />\
		<type label="Integer" length="0" sql="INTEGER" quote="" />\
		<type label="BIGINT" length="0" sql="BIGINT" quote="" />\
		<type label="Decimal" length="1" sql="DECIMAL" re="DEC" quote="" />\
		<type label="Single precision" length="0" sql="FLOAT" quote="" />\
		<type label="Double precision" length="0" sql="DOUBLE" re="DOUBLE" quote="" />\
	</group>\
	<group label="Character" color="rgb(255,200,200)">\
		<type label="Char" length="1" sql="CHAR" quote="\'"/>\
		<type label="Varchar" length="1" sql="VARCHAR"  quote="\'"/>\
		<type label="Text" length="0" sql="MEDIUMTEXT" re="TEXT" quote="\'"/>\
		<type label="Binary" length="1" sql="BINARY" quote="\'"/>\
		<type label="Varbinary" length="1" sql="VARBINARY" quote="\'"/>\
		<type label="BLOB" length="0" sql="BLOB" re="BLOB" quote="\'"/>\
	</group>\
	<group label="Date &amp; Time" color="rgb(200,255,200)">\
		<type label="Date" length="0" sql="DATE" quote="\'" />\
		<type label="Time" length="0" sql="TIME" quote="\'" />\
		<type label="Datetime" length="0" sql="DATETIME" quote="\'" />\
		<type label="Year" length="0" sql="YEAR" quote="" />\
		<type label="Timestamp" length="0" sql="TIMESTAMP" quote="\'" />\
	</group>\
	<group label="Miscellaneous" color="rgb(200,200,255)">\
		<type label="ENUM" length="1" sql="ENUM" quote="" />\
		<type label="SET" length="1" sql="SET" quote="" />\
		<type label="Bit" length="0" sql="bit" quote="" />\
	</group>\
</datatypes>');

var LOCALE = {};
var SQL = {};


$(window).keydown(function(evt) {
	//console.log(evt);
	if (evt.which == 46) { // ctrl
		designer.tableManager.remove();
		
	} else if (evt.which == 45){ //ins
		if (!designer.tableManager.adding)
		designer.tableManager.preAdd();
		
	} else if (evt.which == 27){ //esc
		if (designer.tableManager.adding)
			designer.tableManager.preAdd();
	}
});

/* -------------------- base visual element -------------------- */
SQL = {};

SQL.Visual = {
		  extends: function(parent){
				this._super = parent;
				for(var key in this){
					if (typeof(parent[key]) === "undefined")
						parent[key] = this[key];
				} 
			}
		
		, _super: null
		
		, hide_connector: false
		
		, init: function(){
				if (this._super._init)
					this._super._init();
				else
					this._init();
				
				if (this._super._build)
					this._super._build();
				else
					this._build();
				
				var $this = this._super;
				$(this._super.dom.container).dblclick(function(){
					var props = null;
					switch($this.object_type){
						case "TABLE": props = $this.owner.object_properties; break
						default: props = $this.owner.owner.object_properties; break;
					}

					props.toggle();
					//return false;
				});
			}
		
		, _init: function(){
				this._super.dom = {
					container: null,
					title: null
				};
				this._super.form_code = {
						  ui_group			: "__MAIN__"
						, ui_alignment		: "horizontal"
						, ui_field_type		: "text"
						, name  			: null
						, title 			: null
						, default_value		: null
						, show_on_editor	: true
						, visible			: true
						, show_on_grid		: true
						, show_on_import	: true
						, readonly			: false
						, links				: []
					};
				this._super.data = {
					  title			: ""
					, comment		: ""
					, object_type	: this.object_type
				}
			}
		
		, _build: function(){}
		, toXML: function(){}
		, fromXML: function(){}
		, is_selected: function(){return this._super.selected;}
		, destroy: function(){
				this._super.dom.container.remove();
		}
		
		, set_title: function(text, comment){
				//console.log("setting title: "+ text);
				if (!text) { return; }
				var _title = this._super.form_code.title //text;
				this._super.form_code.name = text;

				if (comment){
					_title += "<p class='comment'>"+comment+"</p>";
				}
				//console.log(this._super);
				$(this._super.dom.container).find(".title:first").html(_title);
		}
		
		, setComment: function(text){
				this._super.form_code.comment = text;
				this.set_title(this._super.form_code.name, this._super.form_code.comment);
		}
		
		, getComment: function() {
				return this._super.form_code.comment;
		}
		
		, getTitle: function(){
				return this._super.form_code.name;
		}
		
		, getZ: function() {
			return this._super.dom.container.css("z-index");
		}
		
		, setZ: function(z) {
			if (!this._super.dom) return;
			this._super.dom.container.css("z-index", z);
		}

		, toFront: function(){
				//console.log("bring to front: "+ this.getTitle());
				//GO THROUGH ALL VISUALS ON CENTER PANE AND

				var z = 1;
				$(".table").each(function(){
					if (parseFloat($(this).css("z-index")) > z)
						z = parseFloat($(this).css("z-index"));
				});

				z_dropped = z - 1;

				$(".table").each(function(){
					if (parseFloat($(this).css("z-index")) == z){
						$(this).css("z-index", z_dropped);
					}
				});

				$(this._super.dom.container).css({"z-index":z});
		}
		
		, redraw: function(){}
};

/* --------------------- table row ( = db column) ------------ */
SQL.Row = function(owner, title, data){
	this.object_type = "FIELD";
	SQL.Visual.extends(this);
	
	this.owner = owner;
	this.relations = [];
	this.keys = [];
	this.selected = false;
	this.expanded = false;

	SQL.Visual.init(this);

	this.form_code.name = title;
	this.data.type = 0;
	this.data.size = "";
	this.data.def = null;
	this.form_code.nullable = true;
	//this.data.ai = false;
	this.form_code.comment = "";

	this.form_code.title			= title;
	this.form_code.name				= title;
	this.form_code.nullable			= true;
	this.form_code.auto_increment	= false;
	
	if (data){
		this.form_code.auto_increment = data.auto_increment || false;
		
		if (typeof data.show_on_import !== "undefined")
			this.form_code.show_on_import = data.show_on_import;

		if (typeof data.show_on_grid !== "undefined")
			this.form_code.show_on_grid = data.show_on_grid;

		if (typeof data.show_on_editor !== "undefined")
			this.form_code.show_on_editor = data.show_on_editor;
		
		if (typeof data.type !== "undefined")
			this.data.type = data.type;
		if (typeof data.nullable !== "undefined")
			this.form_code.nullable = data.nullable;
		
		//if (typeof data.auto_increment !== "undefined")
		//	this.data.ai = data.auto_increment;
		
		if (typeof data.ui_field_type !== "undefined")
			this.form_code.ui_field_type = data.ui_field_type;
	}

	this.form_code.fk_display_field		= null;

	this.build = function() {
		this.dom.container = $('<tr class="table-field">\
									<td class="is_selected" />\
									<td class="title" />\
									<td class="typehint" />\
									<td class="field-type"></td>\
								</tr>');
		//CREATE A REFERENCE TO THE MAIN ROW OBJECT
		this.dom.container.prop("row", this);
		this.dom.container.click($.proxy(function(){
			this.select();
			return false;
		}, this));

		this.dom.container.dblclick($.proxy(function(){
			this.owner.owner.object_properties.toggle();
		}, this));
		
		this.dom.container.keyup($.proxy(function(event){
			//console.log("Keypress: "+event.keyCode);
			switch(event.keyCode){
				case 38: 
					this.up(); 
					break;
				
				case 40:
					this.down();
					break;
			}
		}, this));
		
		var dest = this;
		this.dom.container
			.draggable({
				  revert	: "invalid"
				, helper	: "clone"
			})
			.droppable({
				drop		: function(event, ui){
					var src		= ui.draggable.prop("row");
					dest.owner.owner.addRelation(src, dest);
					dest.redraw();
				}
			});
		
		this.redraw();
	}

	this.select = function() {
		//if (this.selected) { return; }
		this.owner.select();
		this.selected = true;
		//this.redraw();
		
		var selected	= this.dom.container.find(".is_selected");
			selected.html("&raquo;&nbsp;");
			this.dom.container.addClass("selected");
		
		this.owner.owner.rowManager.select(this);
		this.owner.owner.object_properties.attach(this);
	};

	this.deselect = function() {
		//if (!this.selected) { return; }
		this.selected = false;
		var selected	= this.dom.container.find(".is_selected");
			selected.html("");
			this.dom.container.removeClass("selected");
	};

	this.setTitle = function(t) {
		var old = this.form_code.name;
		for (var i=0;i<this.relations.length;i++) {
			var r = this.relations[i];
			if (r.row1 != this) { continue; }
			var tt = r.row2.getTitle().replace(new RegExp(old,"g"),t);
			if (tt != r.row2.getTitle()) { r.row2.set_title(tt); }
		}

		this.set_title(t, this.form_code.comment);
	};

	this.update = function(data) {
		var des = SQL.Designer;
		if (data.nullable && data.def && data.def.match(/^null$/i)) { data.def = null; }

		for (var p in data) { this.form_code[p] = data[p]; }
		if (!this.form_code.nullable && this.data.def === null) { this.data.def = ""; }

		this.redraw();
		
	};

	this.up = function() {
		var r = this.owner.rows;
		var idx = r.indexOf(this);
		if (!idx) { return; }
		r[idx-1].dom.container.get(0).parentNode.insertBefore(this.dom.container.get(0),r[idx-1].dom.container.get(0));
		r.splice(idx,1);
		r.splice(idx-1,0,this);
		//this.redraw();
	};

	this.down = function() {
		var r = this.owner.rows;
		var idx = r.indexOf(this);
		if (idx+1 == this.owner.rows.length) { return; }

		r[idx].dom.container.get(0).parentNode.insertBefore(this.dom.container.get(0),r[idx+1].dom.container.get(0).nextSibling);
		r.splice(idx,1);
		r.splice(idx+1,0,this);
		//this.redraw();
	};

	this.redraw = function() {
		var color = this.getColor();
		//this.dom.container.css("background-color", color);
		
		var pk			= this.isPrimary();
		var title		= this.dom.container.find(".title");
		var typehint	= this.dom.container.find(".typehint");
		var field_type	= this.dom.container.find(".field-type");
		
		title.removeClass("primary");
		title.removeClass("key");
                field_type.html("");
		if (this.isPrimary()){
			title.addClass("primary");
			field_type.html("PK");
		}
		//if (this.isKey()){
		//	title.addClass("key");
		//}
		
		//CHECK IF IT IS A FOREIGN-KEY
		var $this = this;
		for(var i = 0; i < this.owner.owner.relations.length; i++){
			var rel = this.owner.owner.relations[i];
			if (rel.row2 == this){
				field_type.html("FK");
			}
		}
		
		typehint.html("");
		if (true == this.owner.owner.project.show_field_types){
			var type_info = [];
			
			var elm = this.getDataType();
			type_info.push(elm.getAttribute("sql"));

			type_info.push("(" + this.data.size + ")");

			typehint.html(type_info.join(" "));
		}
		
		this.set_title(this.form_code.name, this.form_code.comment);
		
		this.dom.container.show();
		//console.log(this);
		if (this.form_code.name !== null && this.owner.owner.project.implementation_fields.indexOf(this.form_code.name.toLowerCase()) !== -1){
			this.form_code.show_on_editor	= false;
			this.form_code.show_on_grid		= false;
			this.form_code.show_on_import	= false;
			this.dom.container.hide();
		}
	};

	this.addRelation = function(r) {
		if (!in_array(r, this.relations))
			this.relations.push(r);
	};

	this.removeRelation = function(r) {
		var idx = this.relations.indexOf(r);
		if (idx == -1) { return; }
		this.relations.splice(idx,1);
	};

	this.addKey = function(k) {
		this.keys.push(k);
		
	};

	this.removeKey = function(k) {
		var idx = this.keys.indexOf(k);
		if (idx == -1) { return; }
		this.keys.splice(idx,1);
		
	};

	this.getDataType = function() {
		var type = this.data.type;
		var elm = $(DATATYPES).find("type").get(type);
		return elm;
	};

	this.getColor = function() {
		//var elm = this.getDataType();
		//if (elm){
		//	var g = this.getDataType().parentNode;
		//	return elm.getAttribute("color") || g.getAttribute("color") || "#fff";
		//} else {
			return "#fff";
		//}
	};

	this.destroy = function() {
		var $this = this;
		
		//REMOVE ANY RELATION THAT THIS FIELD IS PART OF....
		$(this.owner.owner.relations).each(function(){
			if (this.row1 == $this || this.row2 == $this)
				$this.owner.owner.removeRelation(this);
		});
		
		for (var i=0;i<this.keys.length;i++){
			this.keys[i].removeRow(this);
		}

		this.dom.container.remove();
	};
	
	this.toXML = function() {
		var xml = "";

		var t = this.getTitle().replace(/"/g,"&quot;");
		var nn = (this.form_code.nullable ? "1" : "0");
		var ai = (this.form_code.auto_increment ? "1" : "0");

		xml += '<row name="'+t+'" caption="'+this.form_code.title+'" null="'+nn+'" autoincrement="'+ai+'">\n';

		var elm = this.getDataType();
		var t = elm.getAttribute("sql");
		if (this.data.size.length) { t += "("+this.data.size+")"; }
		xml += "<datatype>"+t+"</datatype>\n";

		if (this.data.def || this.data.def === null) {
			var q = elm.getAttribute("quote");
			var d = this.data.def;
			if (d === null) {
				d = "NULL";
			} else if (d != "CURRENT_TIMESTAMP") {
				d = q+d+q;
			}
			xml += "<default>"+d+"</default>";
		}

		for (var i=0;i<this.relations.length;i++) {
			var r = this.relations[i];

			if (r.row2 != this) { continue; }
			xml += '<relation '+
					'table="'+r.row1.owner.getTitle()+'" '+
					'row="'+r.row1.getTitle()+'" '+
					'fk_display_field="'+r.row1.form_code.fk_display_field+'" '+
					'hide_connector="'+(r.hidden==true?"true":"false")+'" '+
					'/>\n';
		}

		xml += "<form_code>"+$.toJSON(this.form_code)+"</form_code>";

		if (this.form_code.comment) {
			var escaped = this.form_code.comment.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
			xml += "<comment>"+escaped+"</comment>\n";
		}

		xml += "</row>\n";
		return xml;
	};

/*
	this.fromXML = function(node) {
		var name = node.getAttribute("name");
		
		var obj = { type:0, size:"" };
		obj.nullable = (node.getAttribute("null") == "1");
		obj.ai = (node.getAttribute("autoincrement") == "1");
		
		var cs = node.getElementsByTagName("comment");
		if (cs.length && cs[0].firstChild) { obj.comment = cs[0].firstChild.nodeValue; }
		
		var d = node.getElementsByTagName("datatype");
		if (d.length && d[0].firstChild) { 
			var s = d[0].firstChild.nodeValue;
			var r = s.match(/^([^\(]+)(\((.*)\))?.*$/);
			var type = r[1];
			if (r[3]) { obj.size = r[3]; }
			var types = window.DATATYPES.getElementsByTagName("type");
			for (var i=0;i<types.length;i++) {
				var sql = types[i].getAttribute("sql");
				var re = types[i].getAttribute("re");
				if (sql == type || (re && new RegExp(re).exec(type)) ) { obj.type = i; }
			}
		}
		
		var elm = DATATYPES.getElementsByTagName("type")[obj.type];
		var d = node.getElementsByTagName("default");
		if (d.length && d[0].firstChild) { 
			var def = d[0].firstChild.nodeValue;
			obj.def = def;
			var q = elm.getAttribute("quote");
			if (q) {
				var re = new RegExp("^"+q+"(.*)"+q+"$");
				var r = def.match(re);
				if (r) { obj.def = r[1]; }
			}
		}

		this.update(obj);
		this.set_title(name);
	};
*/
	this.toObject = function() {
		var obj = $.extend({}, this.form_code);
		var elm = $(DATATYPES).find("type")[this.data.type];
		var data_type = $(elm).attr("sql");
		if (this.data.size.length) { data_type += "("+this.data.size+")"; }

		obj.name			= this.getTitle();
		obj.alias			= this.getTitle();
		obj.comment			= this.getComment();

		//obj.nullable		= this.form_code.nullable;
		//obj.auto_increment	= this.form_code.auto_increment;
		obj.primary_key		= this.isPrimary();
		obj.data_type		= this.form_code.ui_field_type;
		obj.sql_default		= this.data.def;
		obj.sql_size		= this.data.size;
		obj.sql_type		= data_type;
		
		/*
		obj.default_value	= this.form_code.default_value;
		obj.title			= this.form_code.title;
		obj.show_on_import	= this.form_code.show_on_import;
		obj.show_on_grid	= this.form_code.show_on_grid;
		obj.show_on_editor	= this.form_code.show_on_editor;
		obj.readonly		= this.form_code.readonly;
		obj.ui_group		= this.form_code.ui_group;
		obj.sort_order		= this.form_code.sort_order;
		obj.css_style		= this.form_code.css_style;
		*/
		
		fk					= {};
		var $this = this;
		$(this.owner.owner.relations).each(function(){
			if (this.row2 == $this){
				fk.sql_table	= this.row1.owner.getTitle();
				fk.key			= this.row1.getTitle();
				fk.value		= this.row1.form_code.fk_display_field;
				if (!fk.value) fk.value = fk.key;
			}
		});

		if (fk.sql_table){
			obj.data_type = "lookup";
			obj.foreign_key = fk;
		}
		//console.log(obj);
		return obj;
	};

	this.fromObject = function(node) {
		var name		= node.name;
		var caption		= node.title;
		this.form_code.name	= node.name;
		
		if (!caption || caption == "") caption = name;
		
		if (node.primary_key === true)
			node.auto_increment = true;
		else
			node.auto_increment = false;
		
		var obj = {type:0, size:""};
		obj.nullable = node.nullable;
		obj.auto_increment = node.auto_increment;

		obj.comment = node.comment;
		if (typeof node.ui_group === "undefined" || node.ui_group == null)
			node.ui_group = "__MAIN__";
			
		if (typeof node.form_code === "undefined" || node.form_code == null){
			node.form_code = {
					  caption	: node.title
					, name		: node.name
					, ui_group	: "__MAIN__"
				};
		}
		
		if (!node.sql_type){
			switch(node.data_type){
				case "number":
					if (node.auto_increment === true)
						node.sql_type = "BIGINT(20)";
					else
						node.sql_type = "INT";
					
					break;
				
				case "lookup":
					node.sql_type = "BIGINT(20)";
					break;
				
				case "text":
					node.sql_type = "VARCHAR(50)";
					break;
				
				case "notes":
					node.sql_type = "text";
					break;
					
				case "date":
					node.sql_type = "DATETIME";
					break;
				
				default:
					node.sql_type = "INT";
					break;
			}
		}
		
		if (typeof node.form_code.entity_name === "undefined" || node.form_code.entity_name == null)
			node.form_code.entity_name = node.title;
		
		if (node.sql_type){
			var s = node.sql_type;
			var r = s.match(/^([^\(]+)(\((.*)\))?.*$/);
			var type = r[1];
			if (r[3]) { obj.size = r[3]; }
			var types = window.DATATYPES.getElementsByTagName("type");
			for (var i=0;i<types.length;i++) {
				var sql = types[i].getAttribute("sql");
				var re = types[i].getAttribute("re");
				if (sql == type || (re && new RegExp(re).exec(type)) ) { obj.type = i; }
			}
		}
		var elm = window.DATATYPES.getElementsByTagName("type")[obj.type];
		var def = node.sql_default;
		obj.def = def;
		var q = node.quote;
		if (q) {
			var re = new RegExp("^"+q+"(.*)"+q+"$");
			var r = def.match(re);
			if (r) { obj.def = r[1]; }
		}

		this.form_code = $.extend(true, {}, node);
		this.form_code.title = caption;
		this.form_code.ui_field_type = node.data_type;
		this.update(obj);
		this.set_title(name);
	};

	this.isPrimary = function() {
		if (this.form_code.auto_increment == true) return true;
		return false;
	};

	this.isUnique = function() {
		for (var i=0;i<this.keys.length;i++) {
			var k = this.keys[i];
			var t = k.getType();
			if (t == "PRIMARY" || t == "UNIQUE") { return true; }
		}
		return false;
	};

	this.isKey = function() {
		return this.keys.length > 0;
	};

	this.build();
	//if (data) { this.update(data); }
	this.set_title(this.form_code.name);

};

/* --------------------------- relation (connector) ----------- */
SQL.Relation = function(owner, row1, row2){
	SQL.Visual.extends(this);
	
	SQL.Visual.init(this);
	
	this.object_type = "RELATION";
	
	var connection = null;
	
	if (!row1) return;
	
	row1.addRelation(this);
	row2.addRelation(this);
	//console.log(owner);
	var conn_info = $("<div class='ui-corner-all ui-border-all table'>");
	conn_info.appendTo(owner.dom.container);
	var $this = this;

	var _show = function() {
		if (row1.owner.form_code.visible == false || row2.owner.form_code.visible == false){
			console.log("\tNothing to draw");
			return;
		}

		if (row2.hide_connector == true) return;
		if (owner.project){
			if (row2.form_code.name !== null && owner.project.implementation_fields.indexOf(row2.form_code.name.toLowerCase()) !== -1){
				if (null != connection){
					jsPlumb.detach(connection);
					connection = null;                    
				}
				return;
			}
		}
		
		if (connection != null){
			jsPlumb.detach(connection);
			connection = null;
		}
		
		connection = jsPlumb.connect({
			  source		: row1.owner.dom.container
			, target		: row2.owner.dom.container
			, paintStyle	: {strokeStyle: "rgb(0,0,0)", lineWidth: 2}
			, anchor		: "Continuous"
			, connector		:[ "StateMachine", {gap: 2,cornerRadius: 5, stub: 5, alwaysRespectStubs: true} ]
			, overlays		:[
						  ["Arrow", { width:15, length:10, location:1, id:"arrow" }]
						//, ["Label", {label: row1.form_code.title+" :: "+row2.form_code.title, cssClass:"link_label"}]
			]
			, parameters	: { relationship: {
					  row1    : row1
					, row2    : row2
				}}
		});

		connection.bind("mouseenter", function(conn, evt){
			//console.log("relation: mouse-enter");
			//console.log(evt);
			var msg = "<h3>"+ row1.owner.getTitle()+"."+row1.getTitle()+ "<br> <span class='ui-icon ui-icon-arrowthick-1-s' /> <br>"+
						row2.owner.getTitle()+"."+row2.getTitle() + "</h3>";
						
			conn_info.html(msg);
			conn_info.show();
			conn_info.css({
					  position	: "absolute"
					, top		: evt.clientY
					, left		: evt.clientX
				});
		});
		
		connection.bind("mouseexit", function(conn, evt){
			conn_info.hide();
		});
		
		connection.bind("click", function(conn){
			console.log(row2.owner.getTitle()+"."+row2.getTitle()+ " REFERS TO "+
						row1.owner.getTitle()+"."+row1.getTitle());
		});
		
		jsPlumb.draggable(jsPlumb.getSelector(".table-field")); 
	};

	var _hide = function() {
		if (connection == null) return;
		jsPlumb.detach(connection);
		connection = null;
	};

	var _destroy = function() {
		if (connection != null){
			jsPlumb.detach(connection);
			connection = null;
		} else {
					console.log("connection is null")
				}
		row1.removeRelation(this);
		row2.removeRelation(this);
	};

	_show();
	
	return {
		  owner			: owner
		, row1			: row1
		, row2			: row2
		, data			: this.data
        , connection    : connection
		, show			: _show
		, hide			: _hide
		, destroy		: _destroy
		, redraw		: _show
	};
};

/* --------------------- db table ------------ */
SQL.Table = function(owner, name, x, y){
	this.object_type = "TABLE";
	SQL.Visual.extends(this);

	this.owner				= owner;
	this.rows				= [];
	this.keys				= [];
	this.zIndex				= 0;
	this._ec				= [];
	this.flag				= false;
	this.selected 			= false;
	SQL.Visual.init(this);
	this.form_code.comment	= "";
	this.object_type		= "TABLE";
	this.form_code.title	= name;
	this.form_code.name		= name;//.replace(/ /g,"_");
	
	this.form_report = {group_by: null, fields: [], filter:[]};
	
	this.data.data = [];
	this.server_side = {
			  url			: null
			, create		: null
			, update		: null
			, remove		: null
			, list			: null
		};

	this.x = x || 0;
	this.y = y || 0;
	this.moving = false;
	
	if (typeof this.form_code.entity_name == "undefined")
		this.form_code.entity_name = name;
	
	//REGISTER THE TABLE IN CACHE...FOR LATER USE.
	if (this.form_code.name != ""){
		cache[this.form_code.name] = this.data.data;
	}
	var $this = this;
	
	this.hide = function(){
		$this.form_code.visible = false;
		$this.dom.container.hide();
		$this.hideRelations();
	}
	
	this.show = function(){
		$this.form_code.visible = true;
		$this.dom.container.show();
		$this.showRelations();
		console.log("x:y ==> "+$this.x+":"+$this.y);
	}
	
	var build = function() {
		$this.dom.container = $('<div class="table">\
					<table>\
						<thead>\
							<tr><td colspan="5" class="title"></td></tr>\
						</thead>\
						<tbody />\
					</table>\
				</div>').appendTo($this.owner.dom.container);
		$this.dom.container.resizable({
			  minHeight	: 30
			, resize	: function(){
					jsPlumb.repaintEverything();
				}
		});
		$this.dom.parent = $(".ui-layout-center");

		$this.dom.container.find("table thead").unbind("click").click(function(evt){
			if (true == $this.moving){
				$this.moving = false;
				return;
			}
			
			$($this.rows).each(function(){
				$this.deselect();
			});
			$this.select(evt.ctrlKey);
			return false;
		});

		$this.dom.container
			.find("table thead")
			.droppable({
				drop		: function(event, ui){
					var src					= ui.draggable.prop("row");
					if (typeof src !== "undefined" ){
						var col_opts			= {type: src.data.type, auto_increment:false, nullable:true, show_on_editor:true, show_on_grid:true, show_on_import:true};
						var dest				= $this.addRow(src.owner.form_code.name,col_opts);
						dest.form_code.title	= src.owner.form_code.title;
						
						dest.owner.owner.addRelation(src, dest);
						
						dest.redraw();
					}
					
				}
			});
		//var context = this;
		$this.toFront();
		$this.set_title($this.form_code.name, null);
		$this.moveTo($this.x, $this.y);
		$this.dom.container.draggable({
				  grid			:[10,10]
				, handle		: "table thead"
				, containment	: $this.owner.dom.container
				, start			: function(evt){
					$this.moving = true;
					$this.owner.object_properties.close();
					//COPIED CODE TO MOVE ALL ELEMENTS THAT ARE SELECTED
					posTopArray = [];
					posLeftArray = [];
					if ($(this).hasClass("selected")) {  // Loop through each element and store beginning start and left positions
						$(".selected").each(function(i) {
							thiscsstop = $(this).css('top');
							if (thiscsstop == 'auto') thiscsstop = 0; // For IE

							thiscssleft = $(this).css('left');
							if (thiscssleft == 'auto') thiscssleft = 0; // For IE

							posTopArray[i] = parseInt(thiscsstop);
							posLeftArray[i] = parseInt(thiscssleft);
					   });
					}

					begintop = $(this).offset().top; // Dragged element top position
					beginleft = $(this).offset().left; // Dragged element left position
					
				}
				, drag: function(event, ui) {
					var topdiff = $(this).offset().top - begintop;  // Current distance dragged element has traveled vertically
					var leftdiff = $(this).offset().left - beginleft; // Current distance dragged element has traveled horizontally

					if ($(this).hasClass("selected")) {
						$(".selected").each(function(i) {
							$(this).css('top', posTopArray[i] + topdiff); // Move element veritically - current css top + distance dragged element has travelled vertically
							$(this).css('left', posLeftArray[i] + leftdiff); // Move element horizontally - current css left + distance dragged element has travelled horizontally
						});
					}
					jsPlumb.repaintEverything();
				}
				, stop		: function(evt){
					//NOW FIX THE RELATIONSHIP WIRES
					
					$this.toFront();
					$this.owner.object_properties.close();
					var pos = $this.dom.container.position();
					$this.y = pos.top;
					$this.x = pos.left;
				}
			});
	}

	this.getRelations = function() {
		var arr = [];
		for (var i=0;i<this.owner.relations.length;i++) {
			var rel = this.owner.relations[i];
			if ((rel.row1 && rel.row2) &&(rel.row1.owner == this || rel.row2.owner == this)){
				arr.push(rel);
			}
		}
		return arr;
	};

	this.showRelations = function() {
		var me = this;
		$(this.getRelations()).each(function(){
			this.show();
		});
	};

	this.hideRelations = function() {
		var me = this;
		$(this.getRelations()).each(function(){
			this.hide();
		});
	};

	this.select = function(ctrl_key) {
		console.log("TABLE::select");
		if (true !== ctrl_key){
			for(var i=0; i < this.owner.tables.length; i++){
				if (this.owner.tables[i] != this){
					this.owner.tables[i].deselect();
				}
			}
		}
		
		this.owner.object_properties.attach(this);
		this.selected = true;
		this.dom.container.addClass("selected");
		this.toFront();
		this.owner.tableManager.refresh();
	};

	this.deselect = function() {
		$(this.rows).each(function(){this.deselect(); });

		this.selected = false;
		this.dom.container.removeClass("selected");
	};

	this.addRow = function(title, data) {
		var r = new SQL.Row(this, title, data);
		this.rows.push(r);

		this.dom.container.find("table tbody").append(r.dom.container);
		this.redraw();

		return r;
	};

	this.removeRow = function(r) {
		var idx = this.rows.indexOf(r);
		if (idx == -1) { return; }
		r.destroy();
		this.rows.splice(idx,1);
		this.redraw();
	};

	this.addKey = function(name) {
		var k = new SQL.Key(this, name);
		this.keys.push(k);
		return k;
	};

	this.removeKey = function(key) {
		var idx = this.keys.indexOf(key);
		if (idx == -1) { return; }
		key.destroy();
		this.keys.splice(idx,1);
	};

	this.redraw = function() {
		
	};
	
	this.moveTo = function(x, y) {
		this.x = x - x%10;
		this.y = y - y%10;
		if (this.x < 0) this.x = 0;
		if (this.y < 0 ) this.y = 0;
		
		var parent = $(this.dom.parent);

		$(this.dom.container).css({
			  "left"		: (parent.scrollLeft() + this.x)+"px"
			, "top"			: (parent.scrollTop() + this.y)+"px"
			, "position"	: "absolute"
		});
	};

	this.toObject = function(no_relations) {
		var obj = {};
		
		obj.title				= this.form_code.title;
		obj.comment				= this.getComment();
		obj.sql_table			= this.getTitle();
		obj.ajax_url			= this.server_side.url;
		obj.server_call_list	= this.server_side.list;
		obj.server_call_create	= this.server_side.create;
		obj.server_call_update	= this.server_side.update;
		obj.server_call_remove	= this.server_side.remove;
		obj.server_call_import	= this.server_side.create;
		obj.fields				= [];
		obj.ui_groups			= [];
		obj.links				= [];
		
		var $this = this;
		$(this.rows).each(function(){
			var row = this.toObject();
			
			var ui_grp = {name:this.form_code.ui_group};
			if (!in_array(ui_grp, obj.ui_groups))
				obj.ui_groups.push(ui_grp);
			
			var field = this;
			if ((typeof no_relations === "undefined") ||
				(typeof no_relations !== "undefined" && no_relations == false)){
				$($this.owner.relations).each(function(){
					if (this.row1 == field){
						var link = {
								  sql_table		: this.row2.owner.getTitle()
								, reference		: this.row2.owner.toObject(true)
								, mapping:[{
										  source		: this.row1.getTitle()
										, destination	: this.row2.getTitle()
									}]
							};
							
						if (!in_array(link, obj.links)){
							obj.links.push(link);
						}
					}
				});
			}
			obj.fields.push(row);
		});
		
		obj.keys = [];
		$(this.keys).each(function(){
			obj.keys.push(this.toObject());
		});

		obj.data		= this.data.data;
		obj.form_code	= this.form_code;
		obj.form_report	= this.form_report;
		
		if (this.dom.container.is(":visible")){
			var pos = this.dom.container.position();
			obj.top = pos.top;
			obj.left = pos.left;
		} else {
			obj.top = this.y;
			obj.left = this.x;
		}
		
		return obj;
	};

	this.toXML = function() {
		var t = this.getTitle().replace(/"/g,"&quot;");
		var xml = "";
		xml += '<table x="'+this.x+'" y="'+this.y+'" name="'+t+'" caption="'+this.form_code.title+'" >\n';
		for (var i=0;i<this.rows.length;i++) {
			xml += this.rows[i].toXML();
		}
		for (var i=0;i<this.keys.length;i++) {
			xml += this.keys[i].toXML();
		}
		var c = this.getComment();
		if (c) {
			c = c.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
			xml += "<comment>"+c+"</comment>\n";
		}

		//SAMPLE DATA

		//xml += "<data>"+$.toJSON(this.data.data)+"</data>"
		xml += "<form_code>"+$.toJSON(this.form_code)+"</form_code>";

		xml += "<server_side>"+$.toJSON(this.server_side)+"</server_side>"

		xml += "</table>\n";
		return xml;
	};

	this.toString = function(){
		var html = "";
		var $this = this;
		
		//TITLE
		html += "<h2>"+this.form_code.title+"</h2>";
		html += "<p>"+this.form_code.comment+"</p>";
		
		//USES
		html += "<h3>Uses</h3>";
		html += "<ol>";
		$(this.owner.relations).each(function(){
			if (this.row2 && this.row2.owner == $this)
				html += "<li>"+this.row1.owner.form_code.title+"</li>";
		});
		html += "</ol>";

		//USED BY
		html += "<h3>Used By</h3>";
		html += "<ol>";
		$(this.owner.relations).each(function(){
			if (this.row1 && this.row1.owner == $this)
				html += "<li>"+this.row2.owner.form_code.title+"</li>";
		});
		html += "</ol>";
		
		//COLUMNS
		html += "<h3>Columns</h3>";
		html += "<table>";
		html += "<thead><tr>";
		html += "<th>Name</th>";
		html += "<th>Type</th>";
		html += "<th>Length</th>";
		html += "<th>Nullable</th>";
		html += "<th>Index</th>";
		html += "<th>Description</th>";
		html += "</tr></thead>";
		
		html += "<tbody>";
		$(this.rows).each(function(){
			//console.log(this.form_code);
			if (this.owner.owner.project.implementation_fields.indexOf(this.form_code.name.toLowerCase()) !== -1) return;
			
			html += "<tr>";
				html += "<td>"+this.form_code.title+"</td>";
				html += "<td>"+this.form_code.sql_type+"</td>";
				html += "<td>"+this.data.size+"</td>";
				html += "<td>"+(this.form_code.nullable==true?"Yes":"No")+"</td>";
				if (this.form_code.auto_increment == true){
					html += "<td>Primary Key (Auto-Increment)</td>";
				} else if (typeof(this.form_code.foreign_key) !== "undefined"){
					html += "<td>Foreign Key</td>";
				} else {
					html += "<td></td>";
				}
				html += "<td>"+this.form_code.comment+"</td>";
			html += "</tr>";
		});
		
		html += "</tbody></table>";
		
		//DATA
		html += "<h3>Data</h3>";
		html += "<table>";
		html += "<thead><tr>";
		$(this.rows).each(function(){
			if (this.owner.owner.project.implementation_fields.indexOf(this.form_code.name.toLowerCase()) !== -1) return;
			
			html += "<th>"+this.form_code.title+"</th>";
		});
		
		html += "</tr></thead>";
		
		html += "<tbody>";
		//console.log(">>>>> "+this.form_code.title);
		var fields = this.rows;
		$(this.data.data).each(function(){
			var data = this;
			//console.log(this);
			html += "<tr>";
			$(fields).each(function(){
				if (this.owner.owner.project.implementation_fields.indexOf(this.form_code.name.toLowerCase()) !== -1) return;
				html += "<td>"+ cache.field_value(this.form_code, data[this.form_code.name])+"</td>";
			});

			html += "</tr>";
		});
		
		html += "</tbody></table>";
		
		
		return html;
	};
	
	this.fromObject = function(node) {
		var $this = this;
		this.form_code.comment = node.comment;
		if (typeof node.form_code === "undefined" || node.form_code == null){
			node.form_code = {
					  title		: node.title
					, name		: node.sql_table
					, ui_group	: "__MAIN__"
				};
		}
		
		this.moveTo(node.left, node.top);
		$(node.fields).each(function(){
			var r = $this.addRow("");
			r.fromObject(this);
		});
		
		this.data.data = node.data;
		
		this.server_side = {
				  url			: node.ajax_url
				, create		: node.server_call_create
				, update		: node.server_call_update
				, remove		: node.server_call_remove
				, list			: node.server_call_list
			};

		this.form_code = $.extend(true, this.form_code, node.form_code);
		this.form_code.title = node.form_code.caption || node.form_code.title;
		this.form_code.name  = node.sql_table;
		
		if ("caption" in this.form_code) delete this.form_code["caption"];
		
		this.set_title(node.sql_table, node.comment);
		
		if (node.form_report)
			this.form_report = node.form_report;
		
		if (this.form_code.title == null || $.trim(this.form_code.title) == "")
			this.form_code.title = node.sql_table;
		
		if (typeof this.form_code.entity_name === "undefined" ||
			this.form_code.entity_name == null || 
			$.trim(this.form_code.entity_name) == "")
			this.form_code.entity_name = node.sql_table;
		
		this.owner.table_list_append(this);
		
		//REGISTER THE TABLE IN CACHE...FOR LATER USE.
		if (this.form_code.name != ""){
			cache[this.form_code.name] = this.data.data;
		}
	};
/*
	this.fromXML = function(node) {
		var name = node.getAttribute("name");
		var caption = node.getAttribute("caption");
		var comment = node.getElementsByTagName("comment");

		if (caption == "") caption = name;

		if (comment.length > 0)
			this.form_code.comment = comment[0].innerHTML;

		this.set_title(name, this.form_code.comment);
		
		var x = parseInt(node.getAttribute("x")) || 0;
		var y = parseInt(node.getAttribute("y")) || 0;
		this.moveTo(x, y);
		var rows = node.getElementsByTagName("row");
		for (var i=0;i<rows.length;i++) {
			var row = rows[i];
			var r = this.addRow("");
			r.fromXML(row);
		}
		var keys = node.getElementsByTagName("key");
		for (var i=0;i<keys.length;i++) {
			var key = keys[i];
			var k = this.addKey();
			k.fromXML(key);
		}
		for (var i=0;i<node.childNodes.length;i++) {
			var ch = node.childNodes[i];
			if (ch.tagName && ch.tagName.toLowerCase() == "comment" && ch.firstChild) {
				this.setComment(ch.firstChild.nodeValue);
			}
		}

		var data = $.trim($(node).find("data").text());

		if (null != data && data != "")
			this.data.data = $.parseJSON(data);

		data = null;
		data = $.trim($(node).find("server_side").text());
		if (null != data && data != "")
			this.server_side = $.parseJSON(data);

		data = null;
		data = $.trim($(node).children("form_code").text());
		if (null != data && data != "")
			this.form_code = $.parseJSON(data);
	};
*/
	this.findNamedRow = function(n) {
		for (var i=0;i<this.rows.length;i++) {
			if (this.rows[i].getTitle() == n) { return this.rows[i]; }
		}
		return false;
	};
	
	this.addKey = function(type, name) {
		var i = new SQL.Key(this, type, name);
		this.keys.push(i);
		return i;
	};

	this.getRows = function() {
		return this.rows;
	};

	this.destroy = function() {
		while (this.rows.length) {
			this.removeRow(this.rows[0]);
		}

		this.dom.container.remove();
		
		//REMOVE FROM TABLE-LIST
		$("#dropdown-table-list ul #"+this.form_code.name).remove();
		
		this.owner.object_properties.detach();
	};

	//THIS MUST BE HERE :-(
	build();
}

/* --------------------- db index ------------ */
SQL.Key = function(owner, type, name){
	SQL.Visual.extends(this);
	
	this.owner = owner;
	this.rows = [];
	SQL.Visual.init(this);

	this.data.type = type || "INDEX";
	this.form_code.name = name || "";

	this.setName = function(n) {
		this.form_code.name = n;
	}

	this.getName = function() {
		return this.form_code.name;
	}

	this.setType = function(t) {
		if (!t) { return; }
		this.data.type = t;
		//for (var i=0;i<this.rows.length;i++) { this.rows[i].redraw(); }
	};

	this.getType = function() {
		return this.data.type;
	};

	this.addRow = function(r) {
		if (r.owner != this.owner) { return; }
		this.rows.push(r);
		r.addKey(this);
	};

	this.removeRow = function(r) {
		var idx = this.rows.indexOf(r);
		if (idx == -1) { return; }
		r.removeKey(this);
		this.rows.splice(idx,1);
	};

	this.destroy = function() {
		for (var i=0;i<this.rows.length;i++) {
			this.rows[i].removeKey(this);
		}
	};

	this.getLabel = function() {
		return this.form_code.name || this.data.type;
	};

	this.toObject = function() {
		var key = {};
		key.type = this.getType();
		key.name = this.getName();
		key.parts = [];

		for (var i=0;i<this.rows.length;i++) {
			var r = this.rows[i];
			key.parts.push(r.getTitle());
		}

		return key;
	};

	this.toXML = function() {
		var xml = "";
		xml += '<key type="'+this.getType()+'" name="'+this.getName()+'">\n';
		for (var i=0;i<this.rows.length;i++) {
			var r = this.rows[i];
			xml += '<part>'+r.getTitle()+'</part>\n';
		}
		xml += '</key>\n';
		return xml;
	};

	this.fromXML = function(node) {
		this.setType(node.getAttribute("type"));
		this.setName(node.getAttribute("name"));
		var parts = node.getElementsByTagName("part");
		for (var i=0;i<parts.length;i++) {
			var name = parts[i].firstChild.nodeValue;
			var row = this.owner.findNamedRow(name);
			this.addRow(row);
		}
	};
}
/* --------------------- table manager ------------ */
SQL.TableManager = function(owner){
	var $this	= this;
	this.owner	= owner;
	this.dom	= { 
		  container	: $("#table")
		, area		: owner.dom.container
	};

	this.adding = false;

	var ids = ["addtable","removetable","aligntables","cleartables","edittable","tablekeys"];
	for (var i=0;i<ids.length;i++) {
		this.dom[ids[i]] = $("#"+ids[i]);
	}

	this.dom.area.bind("click", $.proxy(function(event){ this.click(event)},this));
	$("#addtable").click(function(){ $this.preAdd(); });
	$("#cleartables").click(function(){ $this.clear(); });
	$("#removetable").click(function(){ $this.remove(); });
	$("#tablekeys").click(function(){ $this.keys(); });

	this.getSelection = function() {
		var sel = [];
		var tables = this.owner.tables;
		for (var i=0;i<tables.length;i++) {
			if (tables[i].selected == true)
				sel.push(tables[i]);
		}
		this.selection = sel;
		this.processSelection();
	}

	this.addRow = function(e) {
		this.getSelection();
		if (this.selection <= 0) return;

		var newrow = this.selection[0].addRow(_("new field"));
		this.owner.rowManager.select(newrow);
	}

	this.select = function(table, multi) { // * activate table * /
		if (table) {
			if (multi) {
				var i = this.selection.indexOf(table);
				if (i < 0) {
					this.selection.push(table);
				} else {
					this.selection.splice(i, 1);
				}
			} else {
				if (this.selection[0] === table) { return; }
				this.selection = [table];
			}
		} else {
			this.selection = [];
		}
		this.processSelection();
	};

	this.processSelection = function() {
		if (this.selection.length == 1) {
			this.dom.edittable.disabled = false;
			this.dom.tablekeys.disabled = false;
			this.dom.removetable.val(_("Remove table"));
		} else {
			this.dom.edittable.disabled = true;
			this.dom.tablekeys.disabled = true;
		}
		if (this.selection.length) {
			this.dom.removetable.disabled = false;
			if (this.selection.length > 1) { this.dom.removetable.val(_("Remove table")); }
		} else {
			this.dom.removetable.disabled = true;
			this.dom.removetable.val(_("Remove table"));
		}
	};

	this.selectRect = function(x,y,width,height) { // * select all tables intersecting a rectangle * /
		this.selection = [];
		var tables = this.owner.tables;
		var x1 = x+width;
		var y1 = y+height;
		for (var i=0;i<tables.length;i++) {
			var t = tables[i];
			var tx = t.x;
			var tx1 = t.x+t.width;
			var ty = t.y;
			var ty1 = t.y+t.height;
			if (((tx>=x && tx<x1) || (tx1>=x && tx1<x1) || (tx<x && tx1>x1)) &&
				((ty>=y && ty<y1) || (ty1>=y && ty1<y1) || (ty<y && ty1>y1)))
				{ this.selection.push(t); }
		}
		this.processSelection();
	};

	this.refresh = function() {
		this.getSelection();
		this.processSelection();
	}

	this.click = function(e) { // * finish adding new table * /
		var newtable = false;

		if (this.adding) {
			this.adding = false;
			this.dom.area.removeClass("adding");
			this.dom.addtable.val(this.oldvalue);

			var x = e.pageX;
			var y = e.pageY;
			var existing = true;
			var index = 0;
			var tbl_name = _("new_table");
			while(true == existing){
				var found = false;
				$(this.owner.tables).each(function(){
					if (this.getTitle() == tbl_name){
						found = true;
					}
				});
				if (true == found){
					index++;
					tbl_name = _("new_table") + index;
				} else {
					break;
				}
			}

			newtable = this.owner.addTable(tbl_name,x,y);
			var col_opts = {ai:true, nll:false, auto_increment:true, show_on_editor:false, show_on_grid:true, show_on_import:false};
			var id = newtable.addRow("id",col_opts);
			var name = newtable.addRow("name",{ai:false});
			var k = newtable.addKey("PRIMARY","");
			k.addRow(id);
			
			col_opts = {ai:false, show_on_editor:false, show_on_grid:false, show_on_import:false};
			newtable.addRow("created_by", col_opts);
			newtable.addRow("created_on", col_opts);
			newtable.addRow("last_edit_by", col_opts);
			newtable.addRow("last_edit_on", col_opts);
			
			col_opts = {ai:false, show_on_editor:true, show_on_grid:true, show_on_import:true, ui_field_type: "boolean"};
			newtable.addRow("is_visible", col_opts);
			//newtable.addRow("is_visible", col_opts);

			newtable.select();
			this.owner.rowManager.select(false);
			if (this.selection.length == 1) { this.selection[0].select(); }
		} else {
			$(this.owner.tables).each(function(){
				this.deselect();
			});
			
			this.owner.object_properties.detach();
		}

	};

	this.preAdd = function(e) { // * click add new table * /
		//console.log("preAdd");
		if (this.adding) {
			this.adding = false;
			this.dom.area.removeClass("adding");
			this.dom.addtable.val(this.oldvalue);
		} else {
			//console.log("we need to do a add");
			this.adding = true;
			this.dom.area.addClass("adding");
			this.oldvalue = this.dom.addtable.val();
			this.dom.addtable.val("["+_("addpending")+"]");
		}
	};

	this.clear = function(e) { // * remove all tables * /
		if (!this.owner.tables.length) { return; }
		var result = confirm(_("Are your sure you want to remove all the tables")+" ?");
		if (!result) { return; }
		this.owner.clearTables();
	};

	this.remove = function(e) {
		console.log("TableManager -> remove")
		var field_removed = false;
		var $this = this;
		
		this.getSelection();
		var titles = this.selection.slice(0);
		if (titles.length == 0) return;
		if (titles.length == 1){
			console.log("only one table selected");
			//CHECK IF A ROW IS SELECTED, CAUSE MAYBE YOU ARE TRYING TO REMOVE A FIELD
			var table = this.selection.slice(0)[0];
			$(table.rows).each(function(){
				if (this.is_selected() == true){
					field_removed = true;
					$this.owner.rowManager.remove();
				}
			});
		}
		
		if (true == field_removed) return;
		
		for (var i=0;i<titles.length;i++) { titles[i] = "'"+titles[i].getTitle()+"'"; }
		var result = confirm(_("Are you sure you want to remove the following table(s)?\n")+" "+titles.join(", "));
		if (!result) { return; }
		var sel = this.selection.slice(0);
		for (var i=0;i<sel.length;i++) { this.owner.removeTable(sel[i]); }
	};

	this.keys = function(e) { // * open keys dialog * /
		this.getSelection();
		this.owner.keyManager.open(this.selection[0]);
	};

	this.save = function() {

	};
};

/* --------------------- row manager ------------ */
SQL.RowManager = function(owner){
	this.selected = null;

	this.select = function(row) { // * activate a row * /
		if (this.selected === row) { return; }
		if (this.selected) { this.selected.deselect(); }

		this.selected = row;
		if (this.selected) { this.selected.select(); }
	};
	
	this.remove = function(e) {
		var result = confirm(_("Are you sure you want to remove the field")+" '"+this.selected.getTitle()+"' ?");
		if (!result) { return; }
		var t = this.selected.owner;
		this.selected.owner.removeRow(this.selected);

		var next = false;
		if (t.rows) { next = t.rows[t.rows.length-1]; }
		this.select(next);
	};
};

/* ----------------- key manager ---------- */
SQL.KeyManager = function(owner){
	var $this = this;
	return;
	
	this.owner = owner;
	this.dom = {
		container:$("#keys")
	}
	//this.dom.container.hide();
	
	var dlg = $(this.dom.container).dialog({ 
					  autoOpen	: false
					, title		: "Key Manager"
					, width		: 640
					, height	: 400
					, modal		: true
					, resizable	: true
					, draggable	: true
				});
	
	
	var build = function() {
		this.dom.container.find("button").button();
		this.dom.list = $("#keyslist");
		this.dom.type = $("#keytype");
		this.dom.name = $("#keyname");
		this.dom.left = $("#keyleft");
		this.dom.right = $("#keyright");
		this.dom.fields = $("#keyfields");
		this.dom.avail = $("#keyavail");
		this.dom.listlabel = $("#keyslistlabel");

		var types = ["PRIMARY","INDEX","UNIQUE","FULLTEXT"];
		var list = $("#keytype");
		list.children().remove();
		for (var i=0;i<types.length;i++) {
			list.append("<option>"+types[i]+"</option>");
		}
		
		$("#keyslist").button().unbind("change").change(function(){
			$this.switchTo($("#keytype").find("option:selected").index());
		});
		
		$("#keyadd").button().unbind("click").click(function(){
			var type = ($this.table.keys.length ? "INDEX" : "PRIMARY");
			$this.table.addKey(type);
			$this.sync($this.table);
			$this.switchTo($this.table.keys.length-1);
		});
		
		$("#keyremove").button().unbind("click").click(function(){
			var index = $("#keyslist").find("option:selected").index();
			if (index == -1) { return; }
			var r = $this.table.keys[index];
			$this.table.removeKey(r);
			$this.sync();
		});
		
		$("#keyleft").button().unbind("click").click(function(){
			$("#keyavail").find("option:selected").each(function(){
				var row = $this.table.findNamedRow(this.value);
				$this.key.addRow(row);
			});
			$this.switchTo($("#keyslist").find("option:selected").index());
		});
		
		$("#keyright").button().unbind("click").click(function(){
			$("#keyfields").find("option:selected").each(function(){
				var row = $this.table.findNamedRow(this.value);
				$this.key.removeRow(row);
			});
			$this.switchTo($("#keyslist").find("option:selected").index());
		});
	}

	this.sync = function(table) { /* sync content with given table */
		/*
		if (typeof table !== "undefined") this.table = table;
		
		if (!this.table) return;
		
		//this.dlg.dialog("option", "title", _("keyslistlabel").replace(/%s/,table.getTitle()));
		
		var list = $("#keyslist");
		list.children().remove();
		for (var i=0;i<table.keys.length;i++) {
			list.append("<option>"+(i+1)+": "+table.keys[i].getLabel()+"</option>");
		}
		
		if (table.keys.length) {
			this.switchTo(0);
		} else {
			this.disable();
		}
		*/
	};

	var redrawListItem = function() {
		var index = this.table.keys.indexOf(this.key);
		this.option.innerHTML = (index+1)+": "+this.key.getLabel();
	};

	var switchTo = function(index) { /* show Nth key */
		this.enable();
		var k = this.table.keys[index];
		this.key = k;
		
		this.option = this.dom.list.find("option").get(index);

		this.dom.type.find("option").each(function(){
			if ($(this).val() == k.getType())
				$(this).attr("selected", "selected");
		});
		
		this.dom.fields.children().remove();
		
		for (var i=0;i<k.rows.length;i++) {
			var opt = $("<option>")
							.html(k.rows[i].getTitle())
							.val(k.rows[i].getTitle())
							.appendTo(this.dom.fields);
		}
		
		this.dom.avail.children().remove();
		for (var i=0;i<this.table.rows.length;i++) {
			var r = this.table.rows[i];
			if (k.rows.indexOf(r) != -1) { continue; }
			
			var opt = $("<option>")
							.html(r.getTitle())
							.val(r.getTitle())
							.appendTo(this.dom.avail);
		}
	};

	var disable = function() {
		this.dom.fields.children().remove();
		this.dom.avail.children().remove();
		
		this.dom.keyremove.attr("disabled", "disabled");//disabled = true;
		this.dom.left.attr("disabled", "disabled");//disabled = true;
		this.dom.right.attr("disabled", "disabled");//disabled = true;
		this.dom.list.attr("disabled", "disabled");//disabled = true;
		this.dom.name.attr("disabled", "disabled");//disabled = true;
		this.dom.type.attr("disabled", "disabled");//disabled = true;
		this.dom.fields.attr("disabled", "disabled");//disabled = true;
		this.dom.avail.attr("disabled", "disabled");//disabled = true;
	};

	var enable = function() {
		this.dom.keyremove.removeAttr("disabled");//.disabled = false;
		this.dom.left.removeAttr("disabled");//disabled = false;
		this.dom.right.removeAttr("disabled");//disabled = false;
		this.dom.list.removeAttr("disabled");//disabled = false;
		this.dom.name.removeAttr("disabled");//disabled = false;
		this.dom.type.removeAttr("disabled");//disabled = false;
		this.dom.fields.removeAttr("disabled");//disabled = false;
		this.dom.avail.removeAttr("disabled");//disabled = false;
	};
	

	this.open = function(table) {
		this.dlg.dialog("open");
		this.sync(table);
	};

	build();
};

/* --------------------- designer ------------ */
SQL.Designer = function(){
	var $this = this;
	
	this.object_type = "DESIGNER";
	
	SQL.Visual.extends(this);
	this.tables = [];
	this.relations = [];
	this.project = {name:"My Project", database_type: "mysql", implementation_fields:["created_by", "created_on", "last_edit_by", "last_edit_on", "last-edit_on"]}
	this.title = document.title;
	SQL.Visual.init(this);
	
	this.dom.container = $("#area");
	this.dom.container.css({
			  "height"		: 4096
			, "width"		: 4096
			, "position"	: "relative"
			, "top"			: "40px"
			, "overflow"	: "auto"
		});
		
	this.typeIndex	= false;
	this.fkTypeFor	= false;
	this.app_mode	= false;
	
	jsPlumb.bind("dblclick", function(c) {
		var yesno = confirm("Are you sure you want to remove this relationship?");
		if (false == yesno) return;
		var p = c.getParameter("relationship");
				//if (typeof p == "undefined") console.log("no parameter set");
				
		$this.removeRelation(c.getParameter("relationship"));
				//jsPlumb.detach(c);
				
	});
	
	this.sync = function() {
		jsPlumb.repaintEverything();
		
		$(this.relations).each(function(){
			if (typeof this.show === "function") this.show();
		});
		
		$(this.tables).each(function(){
			$(this.rows).each(function(){
				this.redraw();
			});
		});
	};
	
	this.requestDB = function() { // * get datatypes file * /
		if (!this.project) this.project = {};
		var db = this.project.database_type;
		if (!db) db = "mysql";
		var bp = "";//this.getOption("staticpath");
		var url = bp + "db/"+db+"/datatypes.xml";
		var request = {
				  ajax_url	: url
				, raw_data	: true
				//, async		: false
			};
		var $this = this;
		var _load_database = function(data){
			window.DATATYPES = $.parseXML($.trim(data));
			
			$this.flag--;
			if (!$this.flag) { $this.init2(); }
		};
		
		if (location.href.indexOf("file:///") !== 0){
			get_server_data(request, function(data){
				_load_database(data);
			});
		} else {
			$this.flag--;
			if (!$this.flag) { $this.init2(); }
		}
	};
	
	this.init2 = function() { // * secondary init, after locale & datatypes were retrieved *  /
		this.tableManager		= new SQL.TableManager(this);
		this.object_properties	= new SQL.ObjectProperties(this);
		this.rowManager			= new SQL.RowManager(this);
		this.keyManager			= new SQL.KeyManager(this);
		
		this.is_web_app = (location.href.indexOf("file:///") == 0);
		
		$("#toolbar").buttonset();
		$("#options").button({icons:{secondary:"ui-icon-gear"}});
		var $this = this;
		
		$("#btn_new_project").unbind("click").click(function(){
			$this.app_mode = false;
			$this.init_toolbar();
			$this.clearTables();
			$this.project.name = "New Project";
			$this.project.show_field_types = false;
			$this.project.database_type = "mysql";
			
			$("#options").button({label:$this.project.name});
			$("#options").trigger("click");
		});
		
		$("#btn_save_project").unbind("click").click(function(){
			if (false == $this.app_mode)
				$this.project_save($this.toObject());
		});
		
		$("#btn_open_project").unbind("click").click(function(){
			var dlg = $("<div title='Open Project'>");         
			var list = $("<ul class='ui-border-bottom' style='list-style:none;'>").appendTo(dlg);
			
			if (window.File && window.FileReader && window.FileList && window.Blob){
				dlg.append("<input type='file' id='fileInput' style='width:100%;'>");
				
				dlg.find("#fileInput").unbind("change").change(function(){
					_load_local_file();
				});
			}
			var request = {
					  ajax_url		: "projects.php"
					, server_call	: "project_list"
					
				};
				
			var _load_from_server = function(){
					var sel = list.find(".ui-widget-header");
					if (sel.length == 0){
						console.log("nothing selected");
						return;
					}
					
					var request = {
							  ajax_url		: "projects.php"
							, server_call	: "project_load"
							, data			: {project: sel.html()}
						};
					get_server_data(request, function(data){
						$this.fromObject(data);
						$("#options").button({label:$this.project.name});
					});
					
					dlg.dialog("close");
			};

			var _load_local_file = function(){
					var files = dlg.find("#fileInput")[0].files;
					if (files.length == 0){
						alert("No file selected.")
						return;
					}
					var reader = new FileReader();
					reader.onload = function(){
						var json = $.trim(reader.result);

						//IF IT DOES NOT START WITH { AND END IT A } THEN THE STRUCTURE IT NOT VALID
						if (json[0] != "{" && json[json.length-1] != "}"){
							alert("File does not appear to be a valid project file.");
							return;
						}
						json = eval("["+json+"]");
						$this.fromObject(json[0]);
						$("#options").button({label:$this.project.name});
						dlg.dialog("close");
					};

					reader.readAsText(files[0]);  
			};
			
			var _load_from_web_store = function(){
					var sel = list.find(".ui-widget-header");
					if (sel.length == 0){
						console.log("nothing selected");
						return;
					}
					
					var key = sel.html().replace(/ /g, "_");
					if (key in window.localStorage){
						var prj = $.parseJSON(window.localStorage[key]);
						$this.fromObject(prj);
						$("#options").button({label:$this.project.name});
						dlg.dialog("close");
					} else {
						alert("Error find project in the storage!");
					}
			}

			var list_projects = function(){
				if ($this.is_web_app !== true){
					get_server_data(request, function(data){
						$(data.projects).each(function(key, value){
							list.append("<li style='padding:5px;'>"+value+"</li>");
						});

						$(list.find("li")).each(function(){
							set_hover(this);
						});

						$(list.find("li")).click(function(){
							var $this = $(this);
							$this.prop("selected", true);
							$(list.find("li")).removeClass("ui-widget-header");

							$this.addClass("ui-widget-header");
						});

						$(list.find("li")).dblclick(function(){
							var $this = $(this);
							$this.prop("selected", true);
							$(list.find("li")).removeClass("ui-widget-header");

							$this.addClass("ui-widget-header");
							_load_from_server();
						});
					});
				} else {
					if (window.localStorage.project_list){
						var pl = $.parseJSON(window.localStorage.project_list);
						$(pl).each(function(key, value){
							list.append("<li style='padding:5px;'>"+value+"</li>");
						});

						$(list.find("li")).each(function(){
							set_hover(this);
						});

						$(list.find("li")).click(function(){
							var $this = $(this);
							$this.prop("selected", true);
							$(list.find("li")).removeClass("ui-widget-header");

							$this.addClass("ui-widget-header");
						});

						$(list.find("li")).dblclick(function(){
							_load_from_web_store();
						});
					}
				}
			}
			
			dlg.dialog({
				  autoOpen		: false
				, width			: 640
				, height		: 480
				, modal			: true
				, allFields		: []
				, open			: function(event, ui){ list_projects();
				}
				, close: function() {
					
				}
				, buttons		: {
						"Load": function(){
							$this.app_mode = false;
							if (true == $this.is_web_app)
								_load_from_web_store();
							else
								_load_from_server();
							
							$this.init_toolbar();
						}
						, "Open As Web-App": function(){
							$this.app_mode = true;
							if (true == $this.is_web_app)
								_load_from_web_store();
							else
								_load_from_server();
								
							$this.init_toolbar();
						}
					}
			});
			dlg.dialog("open");
		});
		
		$("#btn_json_to_table").unbind("click").click(function(){
			var $dlg = $("<div title='Convert JSON to a table'>");

			if (window.File && window.FileReader && window.FileList && window.Blob){
				$dlg.append("<input type='file' id='fileInput' style='width:100%;'>");
				
				$dlg.find("#fileInput").unbind("change").change(function(){
					_load_local_file();
				});
			}

			var $txt = $("<textarea style='width:100%;height:99%'>").appendTo($dlg);
			
			var _load_local_file = function(){
					var files = $dlg.find("#fileInput")[0].files;
					if (files.length == 0){
						alert("No file selected.")
						return;
					}
					var reader = new FileReader();
					reader.onload = function(){
						var json = $.trim(reader.result);
						_import_tables_from_text(json);
						$dlg.dialog("close");
					};

					reader.readAsText(files[0]);  
			};

			var _import_tables_from_text = function(json){
				if (typeof json == "undefined" || null == json || json.length == 0){
					alert("No JSON text provided");
					return;
				}

				var obj			= "";
				var obj_name	= "";
				var bracket_cnt	= 0;
				var prev_char	= "";
				var obj_start	= false;
				var entities	= [];
				for(var index = 0; index < json.length; index++){
					switch(json[index]){
						case "{": 
							if (bracket_cnt == 0){
								obj_start = true;
								obj = "";
							}
							bracket_cnt++;
							break;

						case "}": bracket_cnt--;
							break;

						case "=":
							//IF BRACKET COUNT IS STILL ZERO IT MEANS WE HAVE REACHED THE 
							//OBJECT NAME
							if (bracket_cnt == 0){
								obj_name = obj.replace("var ", "");

							}
							break;
					}

					obj += json[index];

					if ($.trim(json[index]) != "") prev_char = json[index];

					if (index > 0 && bracket_cnt == 0 && obj_start == true){
						//FOUND A OBJECT SO CONVERT IT.
						obj = eval("["+obj+"]");
						var t = $this.addTable("", 40, 40);
						t.form_code.entity_name = obj_name;
						t.fromObject(obj[0]);
						entities.push(obj[0]);

						obj				= "";
						bracket_cnt		= 0;
						obj_start		= false;
					}
				}

				//NOW TRY TO RE-CREATE THE RELATIONSHIPS
				$(entities).each(function(){
					var table = this;
					$(this.fields).each(function(){
						if (!this.foreign_key) return;
						var t1 = $this.findNamedTable(this.foreign_key.sql_table);
						var r1 = t1.findNamedRow(this.foreign_key.key);

						var t2 = $this.findNamedTable(table.sql_table);
						if (!t2) { return; }
						var r2 = t2.findNamedRow(this.name);
						if (!r2) { return; }
						r1.form_code.fk_display_field = this.foreign_key.value;
						$this.addRelation(r1, r2);
					});
				});
			}
			
			//$dlg.dialog({ autoOpen: false,width: 640,height: 400,modal: true,resizable: true,draggable: true });
			
			$dlg.dialog({
				  autoOpen    : false
				, width       : 640
				, height      : 400
				, modal       : true
				, resizable   : true
				, draggable   : true
				, buttons     :{
				"Import Text": function(){
					var json = $.trim($dlg.find("textarea").val());
					_import_tables_from_text(json);
					$dlg.dialog("close");
				}
			}});

			$dlg.dialog("open");
		});

		$("#btn_csv_to_table").unbind("click").click(function(){
			var $dlg = $("<div title='Convert CSV to a table'>");
			var table_name = null;
			
			if (window.File && window.FileReader && window.FileList && window.Blob){
				$dlg.append("<input type='file' id='fileInput' style='width:100%;'>");
				
				$dlg.find("#fileInput").unbind("change").change(function(){
					_load_local_file();
				});
			}

			var $txt = $("<textarea style='width:100%;height:99%'>").appendTo($dlg);
			
			var _load_local_file = function(){
					var files = $dlg.find("#fileInput")[0].files;
					if (files.length == 0){
						alert("No file selected.")
						return;
					}
					table_name = files[0].name;
					
					var reader = new FileReader();
					reader.onload = function(){
						var json = $.trim(reader.result);
						_import_tables_from_text(json);
						$dlg.dialog("close");
					};

					reader.readAsText(files[0]);  
			};

			var _import_tables_from_text = function(text){
				if (typeof text == "undefined" || null == text || text.length == 0){
					alert("No CSV text provided");
					return;
				}

				var lines = text.split(/\r\n|\n/);
				var headers = lines[0].split(',');
				console.log(headers);
				console.log(lines[1]);
				var t = $this.addTable(table_name, 40, 40);
				t.form_code.entity_name = table_name;
				var col_opts = {ai:false, show_on_editor:true, show_on_grid:true, show_on_import:true};

				for(var index = 0; index < headers.length; index++){
					console.log(headers[index]);
					t.addRow(headers[index], col_opts);
				}
				
				t.data.data = [];
				for(var index = 1; index < lines.length; index++){
					t.data.data.push({});
					var line_data = lines[index].split(",");
					for(var key = 0; key < headers.length; key++){
						var value = "";
						if (key < line_data.length)
							value = line_data[key];
							
						t.data.data[t.data.data.length - 1][headers[key]] = value;
					}
				}
			}
			
			$dlg.dialog({
				  autoOpen    : false
				, width       : 640
				, height      : 400
				, modal       : true
				, resizable   : true
				, draggable   : true
				, buttons     :{
				"Import Text": function(){
					var json = $.trim($dlg.find("textarea").val());
					_import_tables_from_text(json);
					$dlg.dialog("close");
				}
			}});

			$dlg.dialog("open");
		});
		
		$("#btn_generate_sql").unbind("click").click(function(){
			var $dlg = $("<div title='SQL Code'>");
			$dlg.dialog({ autoOpen: false,width: 640,height: 400,modal: true,resizable: true,draggable: true });
			var $txt = $("<textarea style='width:100%;height:99%'>").appendTo($dlg);

			var bp = "";//$this.getOption("staticpath");
			var path = bp + "db/"+$this.project.database_type+"/output.xsl";
			var request = {
					  ajax_url	: path
					, raw_data	: true
				}
			get_server_data(request, function(data){
				var xml = $this.toXML();
				var sql = "";
				var xslDoc = $.parseXML(data);
				try {
					if (window.XSLTProcessor && window.DOMParser) {
						var parser = new DOMParser();
						var xmlDoc = parser.parseFromString(xml, "text/xml");
						var xsl = new XSLTProcessor();
						xsl.importStylesheet(xslDoc);
						var result = xsl.transformToDocument(xmlDoc);
						sql = result.documentElement.textContent;
					} else if (window.ActiveXObject) {
						var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
						xmlDoc.loadXML(xml);
						sql = xmlDoc.transformNode(xslDoc);
					} else {
						throw new Error("No XSLT processor available");
					}
				} catch(e) {
					alert(_("xmlerror")+': '+e.message);
				}

				$txt.val(sql);
				$dlg.dialog("open");
			});
		});

		$("#btn_generate_doc").unbind("click").click(function(){
			var text = $this.toString();
			
			var $dlg = $("<div title='Documentation'>");
			$dlg.dialog({ autoOpen: false,width: 640,height: 400,modal: true,resizable: true,draggable: true });
			
			//var $txt = $("<textarea style='width:100%;height:99%'>").appendTo($dlg);
			//$txt.val(text);
			
			$dlg.append(text);
			$dlg.dialog("open");
		});
		
		$("#btn_generate_code").unbind("click").click(function(){
			var sel = [];
			var text = "";
			var tables = $this.tables;
			for (var i=0;i<tables.length;i++) {
				if (tables[i].selected == true)
					text += tables[i].form_code.entity_name+" = "+JSON.stringify(tables[i].toObject(), null, "\t"); + "\r\n";
			}
			
			//IF NO TABLE IS SELECTED THEN EXPORT EVERYTHING
			if (text == "")
				text = $this.toJSON();
			
			var $dlg = $("<div title='Javascript Code'>");
			$dlg.dialog({ autoOpen: false,width: 640,height: 400,modal: true,resizable: true,draggable: true });
			var $txt = $("<textarea style='width:100%;height:99%'>").appendTo($dlg);
			$txt.val(text);
			$dlg.dialog("open");
		});

		$("#btn_generate_website").unbind("click").click(function(){
			//GENERATE THE SQL-CODE FOR THE DATABSE.
			var bp = "";//$this.getOption("staticpath");
			var path = bp + "db/"+$this.project.database_type+"/output.xsl";
			var request = {
					  ajax_url	: path
					, raw_data	: true
				}
			get_server_data(request, function(data){
				var xml = $this.toXML();
				var sql = "";
				var xslDoc = $.parseXML(data);
				try {
					if (window.XSLTProcessor && window.DOMParser) {
						var parser = new DOMParser();
						var xmlDoc = parser.parseFromString(xml, "text/xml");
						var xsl = new XSLTProcessor();
						xsl.importStylesheet(xslDoc);
						var result = xsl.transformToDocument(xmlDoc);
						sql = result.documentElement.textContent;
					} else if (window.ActiveXObject) {
						var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
						xmlDoc.loadXML(xml);
						sql = xmlDoc.transformNode(xslDoc);
					} else {
						throw new Error("No XSLT processor available");
					}
				} catch(e) {
					alert(_("xmlerror")+': '+e.message);
				}

				var request = {
						  ajax_url		: "projects.php"
						, server_call	: "project_generate_website"
						, data			: $this.toObject()
						, sql_code		: sql
					};
				get_server_data(request, function(data){
					alert("website has been generated. You can view it at: "+data.url);
				});
			});

		});
		
		$("#btn_generate_web_app").unbind("click").click(function(){
			$(".fd-app-container").remove();
			var app = new Application($this.toObject(), function(prj){
				$(prj.erd[0].entities).each(function(){
					var entity = this;
					$($this.tables).each(function(){
						if (this.form_code.name == entity.form_code.name){
							this.data.data = entity.data;
						}
					});
				});
				
				//$("#btn_save_project").trigger("click");
			});
		});
		
		$("#options").click(function(){
			console.log(project_options);
			var obj = $.extend(true, {}, project_options);
			obj.eventName			= null;
			obj.ajax_url			= null;
			obj.upload_url			= "boiler_plate/fileupload.php";
			obj.type				= "edit";
			obj.toolbar				= ["save"];
			cache.database_types	= database_types.data;
			
			$(obj.fields).each(function(){
				switch(this.name){
					case "name": this.default_value = $this.project.name;
						break;
					case "show_field_types": this.default_value = $this.project.show_field_types;
						break;
					case "database_type": this.default_value = $this.project.database_type;
						break;
					case "database": this.default_value = $this.project.database;
						break;
					case "database_server": this.default_value = $this.project.database_server;
						break;
					case "database_username": this.default_value = $this.project.database_username;
						break;
					case "database_password": this.default_value = $this.project.database_password;
						break;
					case "implementation_fields": 
						this.default_value = $this.project.implementation_fields.join("\n<br>");
						break;
				}
			});
			console.log(obj);
			$().lookup_form(obj, function(data){
				console.log("project has been updated");
				console.log(data);
				$this.project.name					= data.name;
				$this.project.database_type			= data.database_type;
				$this.project.database				= data.database;
				$this.project.show_field_types		= data.show_field_types;
				$this.project.database_server		= data.database_server;
				$this.project.database_username		= data.database_username;
				$this.project.database_password		= data.database_password;
				
				var text = $.trim(data.implementation_fields);
				text = text
							.replace(/\n/g,",")
							.replace(/;/,",")
							.replace(/\t/g,",")
							.replace(/<br*>/g, ",")
							.replace(/ /g, ",")
							.split(",");
				
				$this.project.implementation_fields = [];
				for(var i = 0; i < text.length; i++){
					if ($.trim(text[i]) !== "")
						$this.project.implementation_fields.push($.trim(text[i].toLowerCase()));
				}
				$this.sync();
				console.log("project");
				console.log($this.project);
			});
		});
	};
	
	this.init_toolbar = function(){
		if (true == $this.app_mode){
			$("#btn_save_project, #btn_json_to_table, #btn_csv_to_table, #btn_generate_sql, #btn_generate_doc, #btn_generate_code, #table_list, #btn_generate_web_app, #addtable, #cleartables, #options").hide();
		} else {
			$("#btn_save_project, #btn_json_to_table, #btn_csv_to_table, #btn_generate_sql, #btn_generate_doc, #btn_generate_code, #table_list, #btn_generate_web_app, #addtable, #cleartables, #options").show();
		}
	}
	
	this.project_save = function(project_in){
		var request = {
				  ajax_url		: "projects.php"
				, server_call	: "project_save"
				, data			: project_in
			};
		if (false == $this.is_web_app){
			get_server_data(request, function(data){
				set_title("project has been saved");
			});
		} else {
			console.log("save to local-storage.")
			if (!window.localStorage){
				alert("No local-storage available. You need a more modern browser.");
				return;
			}
			
			var pl = window.localStorage.project_list;
			if (typeof pl === "undefined") 
				pl = [];
			else
				pl = $.parseJSON(pl);
			
			var prj = project_in;
			if (pl.indexOf(prj.name) == -1){
				pl.push(prj.name);
				console.log("saving project name to list of projects");
			}
			
			window.localStorage.project_list = JSON.stringify(pl);
			var key = prj.name.replace(/ /g, "_");
			window.localStorage[key] = JSON.stringify(prj);
		}
	}
	
	this.open_as_web_app = function(project_in){
		var app = new Application(project_in, function(prj){
			if (true == $this.app_mode)
				$this.project_save(prj);
				
			/*
			$(prj.erd[0].entities).each(function(){
				var entity = this;
				$($this.tables).each(function(){
					if (this.form_code.name == entity.form_code.name){
						this.data.data = entity.data;
					}
				});
			});
			*/
			//$("#btn_save_project").trigger("click");
		});
	}
	
	this.table_list_append = function(table){
		if ($.trim(table.form_code.name) == ""){
			return;
		}
		var icon_class = "ui-icon ui-icon-check";
		if (table.form_code.visible !== true){
			table.hide();
			icon_class = "";
		}
		var designer = this;
		var table_list = $("#dropdown-table-list ul");
		table_list.append("<li id='"+table.form_code.name+"'><a><span class='check-icon "+icon_class+"' style='float:left;width:20px;'>&nbsp;</span><span'>"+table.form_code.title+"</span></a></li>");
		
		$("#dropdown-table-list ul li").unbind("click").click(function(){
			var $this = $(this);
			var table = designer.findNamedTable(this.id);
			console.log("table-id: "+this.id);
			console.log(table);
			if ($this.find(".check-icon").hasClass("ui-icon-check")){
				table.hide();
				$this.find(".check-icon").removeClass("ui-icon ui-icon-check")
			} else {
				table.show();
				$this.find(".check-icon").addClass("ui-icon ui-icon-check")
			}
		});
	}
	
	this.addTable = function(name, x, y) {
		//console.log("Designer.addTable");
		var t = new SQL.Table(this, name, x, y);
		this.tables.push(t);
		$(this.dom.container).append(t.dom.container);
		this.table_list_append(t);
		
		return t;
	};

	this.removeTable = function(t) {
		//console.log("Designer -> removeTable");
		this.tableManager.select(false);
		this.rowManager.select(false);
		var idx = this.tables.indexOf(t);
		if (idx == -1) {console.log("table not found"); return; }
		t.destroy();
		this.tables.splice(idx,1);
	};

	this.addRelation = function(row1, row2) {
		var r = new SQL.Relation(this, row1, row2);
		this.relations.push(r);
		if (row1) row1.redraw();
		if (row2) row2.redraw();

		return this.relations[this.relations.length - 1];
	};

	this.removeRelation = function(r) {
		for(var idx = 0; idx < this.relations.length; idx++){
			var rel = this.relations[idx];
			if (rel.row1 == r.row1 && rel.row2 == r.row2){
				rel.destroy();
				this.relations.splice(idx, 1);
				rel.row1.redraw();
				rel.row2.redraw();
			}
		}
	};

	this.clearTables = function() {
		while (this.tables.length) { this.removeTable(this.tables[0]); }
		this.set_title(false);
	};
	
	this.findNamedTable = function(name) { // * find row specified as table(row) * /
		for (var i=0;i<this.tables.length;i++) {
			if (this.tables[i].getTitle() == name) { return this.tables[i]; }
		}
	};

	this.toJSON = function() {
		var json = "";

		for (var i=0;i<this.tables.length;i++) {
			json += "\r\n\r\n"+this.tables[i].form_code.entity_name+" = "+JSON.stringify(this.tables[i].toObject(), null, "\t");
		}

		return json;
	};

	this.toObject = function() {
		//var project = this.project;// {name:this.project.name, erd:[]};
		this.project.erd = [];
		erd = {};
		erd.name = "ERD";
		erd.entities = [];
		$(this.tables).each(function(){
			erd.entities.push(this.toObject());
		});
		this.project.erd.push(erd);
		return this.project;
	};

	this.toXML = function() {
		var xml = '<?xml version="1.0" encoding="utf-8" ?>\n';
		//xml += '<!-- SQL XML created by SQL Form Designer -->\n';
		//xml += '<!-- Active URL: ' + location.href + ' -->\n';
		xml += '<sql>\n';

		/* serialize datatypes */
		if (window.XMLSerializer) {
			var s = new XMLSerializer();
			xml += s.serializeToString(window.DATATYPES);
		} else if (window.DATATYPES.xml) {
			xml += window.DATATYPES.xml;
		} else {
			alert(_("errorxml")+': '+e.message);
		}

		for (var i=0;i<this.tables.length;i++) {
			xml += this.tables[i].toXML();
		}
		xml += "</sql>\n";
		return xml;
	};

	this.toString = function(){
		var html = "<html>";
		html += "<head>";
		html += "<meta http-equiv=Content-Type content=\"text/html;\">";
		html += "<title>ERD Doc - "+this.project.name+"</title>";
		html += "<style>";
		html += "\
				.docs h1{\
					font-size		: 2em;\
					font-weight		: bold;\
					font-family		: Arial Black;\
					text-transform	: uppercase;\
					text-align		: center;\
				}\
				.docs h2{\
					background		: #FDE9D9;\
				}\
				.docs h3{\
					margin-left		: 1.5em;\
					font-weight		: bold;\
					font-style		: italic;\
					border-bottom	: 1px solid #DDD9C3;\
				}\
				.docs p{}\
				.docs table{\
					width				: 100%;\
					border-collapse		: collapse; \
					border				: 1px solid #DDD9C3;\
				}\
				.docs td, .docs th{\
					border				: 1px solid #DDD9C3;\
				}\
				.docs th{\
					font-weight			: bold;\
					font-style			: bold;\
					text-align			: center;\
					background			: #DDD9C3;\
				}\
		";
		html += "</style>";
		html += "</head>";
		html += "<body><div class='docs'><h1>"+this.project.name+"</h1>";
		$(this.tables).each(function(){
			html += this.toString();
		});
		
		html += "</div></body></html>";
		return html;
	};
	
	this.fromObject = function(node, clear_existing) {
		//console.log("Designer.fromObject");
		var $this = this;
		if (clear_existing !== false) this.clearTables();
		
		this.object_properties.close();
		this.project = $.extend(true, this.project, node);
		if (typeof node.implementation_fields !== "undefined")
			this.project.implementation_fields = node.implementation_fields;
		
		if (this.project.database_type === "undefined" || this.project.database_type == "" || this.project.database_type == null)
			this.project.database_type = "mysql";
		
		this.requestDB();
		$(".fd-app-container").remove();
		if (designer.app_mode == true){
			designer.open_as_web_app(node);
			return;
		}
		
		$(node.erd).each(function(){
			$(this.entities).each(function(){
				var t = $this.addTable("", 0, 0);
				t.fromObject(this);
			});
		});

		$(node.erd).each(function(){
			$(this.entities).each(function(){
				var table = this;
				$(this.fields).each(function(){
					if (!this.foreign_key) return;
					var t1 = $this.findNamedTable(this.foreign_key.sql_table);
					var r1 = t1.findNamedRow(this.foreign_key.key);
					
					var t2 = $this.findNamedTable(table.sql_table);
					if (!t2) { return; }
					var r2 = t2.findNamedRow(this.name);
					if (!r2) { return; }
					r1.form_code.fk_display_field = this.foreign_key.value;
					$this.addRelation(r1, r2);
				});
			});
		});
	};

	this.fromXML = function(node, clear_existing) {
		if (clear_existing !== false) this.clearTables();
		
		var types = node.getElementsByTagName("datatypes");
		if (types.length) { window.DATATYPES = types[0]; }
		//console.log(window.DATATYPES);
		var tables = node.getElementsByTagName("table");
		for (var i=0;i<tables.length;i++) {
			var t = this.addTable("", 0, 0);
			t.fromXML(tables[i]);
		}

		for (var i=0;i<this.tables.length;i++) { /* ff one-pixel shift hack */
			this.tables[i].select();
			this.tables[i].deselect();
		}

		/* relations */
		var rs = node.getElementsByTagName("relation");
		for (var i=0;i<rs.length;i++) {
			var rel = rs[i];
			var tname = rel.getAttribute("table");
			var rname = rel.getAttribute("row");
			var rhide = rel.getAttribute("hide_connector") == "true" ? true : false;
			var rdisplay = rel.getAttribute("fk_display_field");

			var t1 = this.findNamedTable(tname);
			if (!t1) { continue; }
			var r1 = t1.findNamedRow(rname);
			if (!r1) { continue; }
			r1.hide_connector = rhide;

			tname = rel.parentNode.parentNode.getAttribute("name");
			rname = rel.parentNode.getAttribute("name");

			var t2 = this.findNamedTable(tname);
			if (!t2) { continue; }
			var r2 = t2.findNamedRow(rname);
			if (!r2) { continue; }
			r2.hide_connector = rhide;
			r1.form_code.fk_display_field = rdisplay;
			this.addRelation(r1, r2);
		}
	};

	this.setTitle = function(t) {
		document.title = this.title + (t ? " - "+t : "");
	};

	this.getTypeIndex = function(label) {
		if (!this.typeIndex) {
			this.typeIndex = {};
			var types = window.DATATYPES.getElementsByTagName("type");
			for (var i=0;i<types.length;i++) {
				var l = types[i].getAttribute("label");
				if (l) { this.typeIndex[l] = i; }
			}
		}
		return this.typeIndex[label];
	};

	this.getFKTypeFor = function(typeIndex) {
		if (!this.fkTypeFor) {
			this.fkTypeFor = {};
			var types = window.DATATYPES.getElementsByTagName("type");
			for (var i=0;i<types.length;i++) {
				this.fkTypeFor[i] = i;
				var fk = types[i].getAttribute("fk");
				if (fk) { this.fkTypeFor[i] = this.getTypeIndex(fk); }
			}
		}
		return this.fkTypeFor[typeIndex];
	};

	//THIS MUST BE HERE
	this.flag = 1;
	this.requestDB();

};


//======================================================================
// PROPERTIES WINDOW
SQL.ObjectProperties = function(_designer) {
	
	var attached_object = null;
	var designer		= _designer;

	widget =$("<div title='Table Properties'/>"); //$(".ui-layout-south");

	function _build(){
		widget.append('<div class="table_attr_tabs"> \
				<ul>\
					<li><a href="#prop-page-general">General</a></li> \
					<li><a href="#prop-page-data">Data</a></li> \
					<li><a href="#prop-page-report">Reporting</a></li>\
					<li><a href="#prop-page-keys">Keys</a></li> \
				</ul>\
				<div id="prop-page-general" style="width:350px">\
					<div class="-widget-container" style="width:350px">\
						<div class="widget-header">Actions</div>\
						<div class="widget-content" style="height:30px;">\
							<div id="table-actions">\
								<div class="table-add" title="Add Table" id="table_add"/>\
								<div class="table-remove" title="Remove Table" id="table_remove"/>\
								<div class="table-column-add" title="Add Column" id="col_add"/>\
								<div class="table-column-remove field-props" title="Remove Column" id="col_remove" />\
								<button id="col_up" class="field-props">Field Up</button>\
								<button id="col_down" class="field-props">Field Down</button>\
							</div>\
						</div>\
					</div>\
					<div class="-widget-container" style="width:350px">\
						<div class="widget-header">General</div>\
						<div class="widget-content">\
							<p style="display:none"><label for="type">Type</label>\
							<input type="text" id="type" class="form_data ui-widget " />\
							</p>\
							<p><label for="caption">Title</label>\
								<input type="text" id="caption" class="form_data ui-widget " />\
							</p>\
							<p><label for="comment">Comment</label>\
								<input id="comment" type="text" class="form_data ui-widget " />\
							</p>\
							<p class="field-props"><label for="ui_field_type">Type</label>\
								<select id="ui_field_type" class="form_data ui-widget" style="width:40px;" />\
							</p>\
							<p style="display:none"><label for="title">Database Name</label>\
							<input type="text" id="title" readonly class="form_data ui-widget " />\
							</p>\
							<p class="field-props"><label for="auto_increment">Auto-increment</label>\
							<input type="checkbox" id="auto_increment" class="form_data ui-widget " />\
							</p>\
							<p class="field-props"><label for="nullable">Nullable</label>\
							<input type="checkbox" id="nullable" class="form_data ui-widget " />\
							</p>\
							<p class="field-props"><label for="required">Required</label>\
							<input type="checkbox" id="required" class="form_data ui-widget " />\
							</p>\
						</div>\
					</div>\
					<div class="-widget-container" style="width:350px">\
						<div class="widget-header">User Interface</div>\
						<div class="widget-content">\
							<p class="table-props" ><label for="ui_alignment">UI Alignment</label>\
							<select id="ui_alignment" class="form_data ui-widget">\
								<option></option>\
								<option value="vertical">vertical</option>\
								<option value="horizontal">horizontal</option>\
							</select>\
							</p>\
							<p class="table-props" ><label for="ui_app_category">Application Category</label>\
							<select id="ui_app_category" class="form_data ui-widget">\
								<option></option>\
								<option value="menu">Menu</option>\
								<option value="setting">Settings</option>\
								<option value="hidden">Hidden</option>\
							</select>\
							</p>\
							<div class="table-props ui-border-top app-toolbar-settings">\
								<p class="label" style="margin:0;">Toolbar Settings</p>\
								<div style="float:left;margin:5px;">\
									<p class="label">Create</p>\
										<input type="checkbox" id="toolbar_create" checked class="form_data ui-widget " />\
								</div>\
								<div style="float:left;margin:5px;">\
									<p class="label">Update</p>\
										<input type="checkbox" id="toolbar_update" checked class="form_data ui-widget " />\
								</div>\
								<div style="float:left;margin:5px;">\
									<p class="label">Remove</p>\
										<input type="checkbox" id="toolbar_remove" checked class="form_data ui-widget " />\
								</div>\
								<div style="float:left;margin:5px;">\
									<p class="label">Import</p>\
										<input type="checkbox" id="toolbar_import" checked class="form_data ui-widget " />\
								</div>\
								<div style="float:left;margin:5px;">\
									<p class="label">Export</p>\
										<input type="checkbox" id="toolbar_export" checked class="form_data ui-widget " />\
								</div>\
								<div style="float:left;margin:5px;">\
									<p class="label">Search</p>\
										<input type="checkbox" id="toolbar_search" checked class="form_data ui-widget " />\
								</div>\
							</div>\
							<p class="field-props"><label for="ui_group">Panel</label>\
							<input type="text" id="ui_group" class="form_data ui-widget " />\
							</p>\
							<p class="field-props"><label for="ui_default">Default Value</label>\
							<input type="text" id="ui_default" class="form_data ui-widget " />\
							</p>\
							<p class="field-props"><label for="lookup_sort_order">Sort Order</label>\
								<select id="lookup_sort_order" class="form_data ui-widget">\
									<option></option>\
									<option value="ASC">Ascending</option>\
									<option value="DESC">Descending</option>\
								</select>\
							</p>\
							<p class="field-props"><label for="css_style">CSS Style</label>\
							<input type="text" id="css_style" class="form_data ui-widget " />\
							</p>\
							<p class="field-props"><label for="readonly">Read only</label>\
							<input type="checkbox" id="readonly" class="form_data ui-widget " />\
							</p>\
							<div  class="field-props ui-border-top">\
								<p class="label" style="margin:0;">Show on</p>\
								<div style="float:left;margin:5px;">\
									<p class="label">Grid</p>\
										<input type="checkbox" id="show_on_grid" checked class="form_data ui-widget " />\
								</div>\
								<div style="float:left;margin:5px;">\
									<p class="label">Editor</p>\
										<input type="checkbox" id="show_on_editor" checked class="form_data ui-widget " />\
								</div>\
								<div style="float:left;margin:5px;">\
									<p class="label">Import</p>\
										<input type="checkbox" id="show_on_import" checked class="form_data ui-widget " />\
								</div>\
							</div>\
							<!--<p class="field-props"><label for="linked_filter">Linked Filter</label>\
							<button id="linked_filter" class="form_data ui-widget ">Edit Filter</button>\
							</p>-->\
						</div>\
					</div>\
					<div class="field-props -widget-container" style="width:350px">\
						<div class="widget-header">Reference</div>\
						<div class="widget-content">\
							<p><label for="fk_table">Table</label>\
							<select id="fk_table" class="form_data ui-widget " />\
							</p>\
							<p><label for="fk_field">Field</label>\
							<select id="fk_field" class="form_data ui-widget " />\
							</p>\
							<p><label for="fk_display_field">Display Field</label>\
							<select id="fk_display_field" class="form_data ui-widget " />\
							</p>\
							<p><label for="hide_connector">Hide Connector</label>\
							<input type="checkbox" id="hide_connector" class="form_data ui-widget " />\
							</p>\
						</div>\
					</div>\
					<div class="field-props -widget-container" style="width:350px">\
						<div class="widget-header">Database</div>\
						<div class="widget-content">\
							<p><label for="datatype">Data-Type</label>\
							<select id="datatype" class="form_data ui-widget" />\
							</p>\
							<p><label for="data_len">Length</label>\
							<input type="text" id="data_len" class="form_data ui-widget " />\
							</p>\
							<p><label for="data_default">Default</label>\
							<input type="text" id="data_default" class="form_data ui-widget " />\
							</p>\
						</div>\
					</div>\
					<div  class="table-props" id="prop-page-code" style="width:350px">\
						<div class="widget-header">Server Functions</div>\
						<div class="widget-content">\
							<p style="display:none"><label for="entity_name">Entity Name</label>\
								<input id="entity_name" class="form_data ui-widget " />\
							</p>\
							<p><label for="server_url">Server page</label>\
								<input type="text" id="server_url" class="form_data ui-widget " />\
							</p>\
							<p><label for="server_list">List Function</label>\
								<input type="text" id="server_list" class="form_data ui-widget " />\
							</p>\
							<p><label for="server_create">Create Function</label>\
								<input type="text" id="server_create" class="form_data ui-widget " />\
							</p>\
							<p><label for="server_update">Update Function</label>\
								<input type="text" id="server_update" class="form_data ui-widget " />\
							</p>\
							<p><label for="server_remove">Remove Function</label>\
								<input type="text" id="server_remove" class="form_data ui-widget " />\
							</p>\
						</div>\
					</div>\
				</div>\
				<div id="prop-page-report" style="width:350px">\
					<div>\
						<div class="widget-header">General</div>\
						<div class="widget-content">\
							<p><label for="report_group_by">Group By</label>\
							<select id="report_group_by" class="form_data ui-widget " />\
							<button id="btn-create-report">Create Report</button>\
							</p>\
						</div>\
					</div>\
					<div class="widget-container">\
						<div class="widget-header">Filter</div>\
						<div class="widget-content" id="report-filter"/>\
					</div>\
					<div class="widget-container">\
						<div class="widget-header">Fields</div>\
						<div class="widget-content" id="report-fields" />\
					</div>\
				</div>\
				<div id="prop-page-data"></div>\
				<div id="prop-page-keys">\
					<div class="-widget-container">\
						<div class="widget-header">Add New</div>\
						<div class="widget-content" id="report-fields" >\
							<p>\
								<label for="keyname">Name</label>\
								<input type="text" id="keyname" class="ui-widget" />\
								<select id="keytype" />\
								<button id="keyadd">Add Key</button>\
							</p>\
						</div>\
					</div>\
					<div class="-widget-container">\
						<div class="widget-header">Existing</div>\
						<div class="widget-content" id="report-fields" >\
							<fieldset>\
								<select id="keyslist"></select>\
								<button id="keyremove">Key Remove</button>\
							</fieldset>\
							<table>\
								<tbody>\
									<tr>\
										<td>\
											<label for="keyfields" id="keyfieldslabel"></label><br/>\
											<select id="keyfields" size="5" multiple="multiple" style="width:200px;"></select>\
										</td>\
										<td>\
											<button id="keyleft" value="&lt;&lt;">&lt;&lt;</button><br/>\
											<button id="keyright" value="&gt;&gt;">&gt;&gt;</button><br/>\
										</td>\
										<td>\
											<label for="keyavail" id="keyavaillabel"></label><br/>\
											<select id="keyavail" size="5" multiple="multiple" style="width:200px;"></select>\
										</td>\
									</tr>\
								</tbody>\
							</table>\
						</div>\
					</div>\
				</div>\
				</div>');

		widget.find(".table_attr_tabs").tabs();
		//widget.find("#table-actions").buttonset();
		widget.find("#linked_filter").button();
		
		widget.hover(function(){
				widget.parent().css({"opacity":"1"});
			}
			, function(){
				widget.parent().css({"opacity":"0.4"});
			});
		widget.find("#prop-page-general").children("div").fd_panel();
		widget.find("#prop-page-report").children("div").fd_panel();
		widget.find("#prop-page-keys").children("div").fd_panel();
		
	}

	function _update_title(){
		if (!attached_object) return;
		
		if (attached_object.object_type == "FIELD"){
			widget.dialog("option", "title", attached_object.owner.form_code.title +" [ "+ attached_object.form_code.title+" ]");
		} else {
			widget.dialog("option", "title", attached_object.form_code.title);
		}

		
	}
	
	function _setup_data_tab(){
		//console.log("_setup_data_tab");
		if (!attached_object){
			console.log("No object selected");
			return;
		}
		var table = attached_object;

		if (attached_object.object_type == "FIELD"){
			table = attached_object.owner;
		}

		if (!table.data.data){
			table.data.data = [];
		}

		var obj = table.toObject();
		//obj = $.extend(obj, obj.form_code);
		obj.eventName = null;
		obj.ajax_url = null;
		obj.content_area = "#prop-page-data";
		obj.upload_url = "boiler_plate/fileupload.php";
		obj.alignment = table.form_code.ui_alignment;
		obj.data = table.data.data;
		console.log("TABLE OBJECT");
		console.log(obj);
		//cache = {};
		$(designer.tables).each(function(){
			cache[this.form_code.name] = this.data.data;
		});

        $().lookup_form(obj, function(data){
			table.data.data = data;
		});
	}
	
	function _attach_events(){
		widget.find("#linked_filter").unbind("click").click(function(){
			console.log("got here");
			var fe = new SQL.FilterEditor(attached_object);
			fe.show();
		});
		
		widget.find(".table_attr_tabs").on("tabsactivate", function( event, ui ){
			if (ui.newPanel.is("#prop-page-data")){
				_setup_data_tab();
			} else if (ui.newPanel.is("#prop-page-report")){
				_init_report();
			}
		});

		widget.find(".form_data").unbind("focus").focus(function(){
			_setup_data_tab();
		});
		
		widget.find("#table_add").unbind("click").click(function(){
				if (!designer) return;

				designer.tableManager.preAdd();
			});
			
		widget.find("#table_remove").unbind("click").click(function(){
				if (!designer) return;
				if (!attached_object) return;

				designer.tableManager.remove(attached_object);
			});
			
		widget.find("#table_code").unbind("click").click(function(){
				if (!attached_object){
					alert("No object selected");
					return;
				}
				var table = attached_object;

				if (attached_object.object_type == "FIELD"){
					table = attached_object.owner;
				}

				if (!table.data.data){
					table.data.data = [];
				}

				var obj = table.toObject();
				obj.eventName = null;
				obj.ajax_url = null;
				obj.upload_url = "boiler_plate/fileupload.php";
				obj.data = table.data.data;
				//cache = {};
				$(designer.tables).each(function(){
					cache[this.getTitle()] = this.data.data;
				});
				$().lookup_form(obj, function(data){
					table.data.data = data;
				});
			})
			.button({icons:{primary:"ui-icon-play"}});

		widget.find("#form_edit").unbind("click").click(function(){
				if (!attached_object){
					alert("No object selected");
					return;
				}
				var table = attached_object;

				if (attached_object.object_type == "FIELD"){
					table = attached_object.owner;
				}

				if (!table.data.data){
					table.data.data = [];
				}

				var obj = table.toObject();
				obj.eventName = null;
				obj.ajax_url = null;
				obj.upload_url = "boiler_plate/fileupload.php";
				obj.data = table.data.data;
				obj.type = "edit";
				//cache = {};
				$(designer.tables).each(function(){
					cache[this.getTitle()] = this.data.data;
				});
				$().lookup_form(obj, function(data){
					console.log(data);
				});
			})
			.button();
		
		widget.find("#col_add").unbind("click").click(function(){
				if (!designer) return;

				designer.tableManager.addRow();
			});
			
		widget.find("#col_remove").unbind("click").click(function(){
				if (!designer) return;

				designer.rowManager.remove();
			});
			
		widget.find("#col_up").unbind("click").click(function(){
				if (!attached_object) return;

				attached_object.up();
			})
			.button({icons:{primary:"ui-icon-arrowthick-1-n"}});

		widget.find("#col_down").unbind("click").click(function(){
				if (!attached_object) return;

				attached_object.down();
			})
			.button({icons:{primary:"ui-icon-arrowthick-1-s"}});

		widget.find("#col-actions").buttonset();

		//GENERAL
		widget.find("#css_style").unbind("keyup").keyup(function(){
			attached_object.form_code.css_style = $(this).val();
		});

		widget.find("#caption").unbind("focus").focus(function(){
			old_name = attached_object.form_code.name;
		});
		
		widget.find("#caption").unbind("focusout").focusout(function(){
			if (attached_object.object_type != "FIELD") return;
			if (attached_object.form_code.name == old_name) return;
			var table = attached_object.owner;
			
			$(table.data.data).each(function(){
				this[attached_object.form_code.name] = this[old_name];
				delete this[old_name];
			});
			
			var obj = table.form_report.fields;
			$(obj).each(function(){
				if (this.table == table.form_code.name){
					if (this.field == old_name){
						this.field = attached_object.form_code.name;
						this.caption = attached_object.form_code.title;
					}
				}
			});
			
			var obj = table.form_report.filter;
			if (obj.indexOf(old_name) !== -1)
				obj[obj.indexOf(old_name)] = attached_object.form_code.name;
		});
		
		widget.find("#caption").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.form_code.title = $(this).val();
			var db_name = attached_object.form_code.title.toLowerCase().replace(/( )/g, "_");
			attached_object.form_code.name = db_name;
			attached_object.form_code.entity_name = db_name;
			attached_object.set_title(db_name);
			attached_object.redraw();
			
			widget.find("#entity_name").val(db_name);
			
			widget.find("#title").val(db_name);
		});

		widget.find("#comment").unbind("keyup").keyup(function(){
			if (!attached_object) return;
			
			attached_object.setComment($(this).val());
		});

		//COLUMN
		widget.find("#datatype").unbind("change").change(function(){
			if (!attached_object) return;
			attached_object.data.type = $(this).prop("selectedIndex");
			attached_object.redraw();
		});

		widget.find("#data_len").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.data.size = $(this).val();
			attached_object.redraw();
		});

		widget.find("#data_default").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.data.def = $(this).val();
			attached_object.redraw();
		});

		widget.find("#auto_increment").unbind("click").click(function(){
			if (!attached_object) return;

			attached_object.form_code.auto_increment = this.checked;
			attached_object.primary_key = this.checked;
			widget.find("#nullable").removeAttr("disabled");
			if (true == this.checked){
				widget.find("#nullable").removeAttr("checked");
				widget.find("#nullable").attr("disabled", "disabled");
				attached_object.form_code.nullable = false;
			}
			
			attached_object.redraw();
		});

		widget.find("#nullable").unbind("click").click(function(){
			if (!attached_object) return;

			attached_object.form_code.nullable = this.checked;
			attached_object.redraw();
		});

		widget.find("#required").unbind("click").click(function(){
			if (!attached_object) return;

			attached_object.form_code.required = this.checked;
			//attached_object.redraw();
		});

		//FOREIGN KEY
		widget.find("#hide_connector").unbind("click").click(function(){
			if (!attached_object) return;
			var table = attached_object;
			if (attached_object.object_type == "FIELD") table = attached_object.owner;
			
			attached_object.hide_connector = this.checked;
			//console.log("hide connector");
			$(table.owner.relations).each(function(){
				if (this.row2 != attached_object) return;
				
				console.log(this);
				if (attached_object.hide_connector == true)
					this.hide();
				else
					this.show();
			});
		});

		//SERVER-SIDE
		widget.find("#entity_name").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.form_code.entity_name = $(this).val();
		});

		widget.find("#server_url").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.server_side.url = $(this).val();
		});

		widget.find("#server_create").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.server_side.create = $(this).val();
		});

		widget.find("#server_update").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.server_side.update = $(this).val();
		});

		widget.find("#server_remove").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.server_side.remove = $(this).val();
		});

		widget.find("#server_list").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.server_side.list = $(this).val();
		});

		//COLUMN - JAVASCRIPT CODE
		widget.find("#lookup_sort_order").unbind("change").change(function(){
			if (!attached_object) return;
			attached_object.form_code.sort_order = $(this).val();
		});
		
		widget.find("#ui_default").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.form_code.default_value = $(this).val();
		});

		widget.find("#ui_group").unbind("keyup").keyup(function(){
			if (!attached_object) return;

			attached_object.form_code.ui_group = $(this).val();
		});

		widget.find("#readonly").unbind("click").click(function(){
			if (!attached_object) return;

			attached_object.form_code.readonly = this.checked;
		});

		widget.find("#show_on_editor").unbind("click").click(function(){
			if (!attached_object) return;

			attached_object.form_code.show_on_editor = this.checked;
		});

		widget.find("#show_on_grid").unbind("click").click(function(){
			if (!attached_object) return;

			attached_object.form_code.show_on_grid = this.checked;
		});

		widget.find("#show_on_import").unbind("click").click(function(){
			if (!attached_object) return;

			attached_object.form_code.show_on_import = this.checked;
		});

		widget.find("#ui_field_type").unbind("change").change(function(){
			if (!attached_object) return;
			
			attached_object.form_code.ui_field_type = this.value;
		});

		//TABLE - JAVASCRIPT CODE
		widget.find("#ui_alignment").unbind("change").change(function(){
			if (!attached_object) return;

			if (attached_object.object_type === "FIELD") return;
			
			attached_object.form_code.ui_alignment = $(this).val();
		});
		
		widget.find("#ui_app_category").unbind("change").change(function(){
			if (!attached_object) return;

			if (attached_object.object_type === "FIELD") return;
			
			attached_object.form_code.app_category = $(this).val();
		});
		
		widget.find("#toolbar_create,#toolbar_update,#toolbar_remove,#toolbar_import,#toolbar_export,#toolbar_search").unbind("click").click(function(){
			if (!attached_object) return;
			
			attached_object.form_code.toolbar = [];
			if ($("#toolbar_create").is(":checked")) attached_object.form_code.toolbar.push("create");
			if ($("#toolbar_update").is(":checked")) attached_object.form_code.toolbar.push("update");
			if ($("#toolbar_remove").is(":checked")) attached_object.form_code.toolbar.push("remove");
			if ($("#toolbar_import").is(":checked")) attached_object.form_code.toolbar.push("import");
			if ($("#toolbar_export").is(":checked")) attached_object.form_code.toolbar.push("export");
			if ($("#toolbar_search").is(":checked")) attached_object.form_code.toolbar.push("search");
			
			console.log("toolbar options");
			console.log(attached_object.form_code.toolbar);
		});
	}

	_build();
	_attach_events();
	
	widget.dialog({
				  autoOpen		: false
				, height		: 600
				, width			: 400
				, minWidth		: 400
				, modal			: false
				, open			: function(event, ui){
					widget.parent().css({"opacity":"0.4"});
				}
				, close: function() {
					//if (options._callback) options._callback(options.data);
				}
				, dragStart: function(){
						//widget.parent().css({"opacity":"0.2"});
					}
				, dragStop: function(){
						//widget.parent().css({"opacity":"1"});
					}
			});
	
	var select = widget.find("#datatype");
	select.children().remove();
	$(DATATYPES).find("group").each(function(){
		var g = $(this);
		var og = $("<optgroup>")
					.appendTo(select)
					.attr("label", g.attr("label"))
					.css({
						"background-color": g.attr("color") || "#fff"
					});

		g.find("type").each(function(){
			var t = $(this);
			var o = $("<option>").val(t.attr("label")).html(t.attr("label")).appendTo(og);

			if (t.attr("color")) { o.css("background-color", t.attr("color")); }
			if (t.attr("note")) { o.attr("title", t.attr("note")); }
		});
	});

	function _init_general_fields(){
		var obj = attached_object;

		widget.find("#type").val(obj.object_type);
		widget.find("#title").val(obj.form_code.name);
		widget.find("#caption").val(obj.form_code.title);
		widget.find("#comment").val(obj.form_code.comment);
		widget.find("#data_default").val(obj.data.def);
		widget.find("#entity_name").val(obj.form_code.entity_name);
		widget.find("#css_style").val(obj.form_code.css_style);
		
		//obj.form_code.auto_increment = obj.data.auto_increment || false;
		
		if (obj.object_type == "TABLE"){
			if (obj.server_side.url == null){
				obj.server_side.url			= "./lookup_tables.php";
				obj.server_side.create		= "lookup_create_item";
				obj.server_side.update		= "lookup_update_item";
				obj.server_side.remove		= "lookup_remove_item";
				obj.server_side.list		= "lookup_read";
			}

			widget.find("#server_url").val(obj.server_side.url);
			widget.find("#server_create").val(obj.server_side.create);
			widget.find("#server_update").val(obj.server_side.update);
			widget.find("#server_remove").val(obj.server_side.remove);
			widget.find("#server_list").val(obj.server_side.list);
		}

		widget.find("#ui_alignment option").each(function(){
			$(this).removeAttr("selected");
			if (this.value == obj.form_code.ui_alignment)
				$(this).attr("selected", "selected");
		});
		
		widget.find("#ui_app_category option").each(function(){
			$(this).removeAttr("selected");
			if (this.value == obj.form_code.app_category)
				$(this).attr("selected", "selected");
		});
		
		widget.find("#lookup_sort_order option").each(function(){
			$(this).removeAttr("selected");
			if (this.value == obj.form_code.sort_order)
				$(this).attr("selected", "selected");
		});
		
		if (obj.form_code.auto_increment == true)
			widget.find("#auto_increment").attr("checked", "checked");
		else
			widget.find("#auto_increment").removeAttr("checked");

		if (obj.form_code.nullable == true)
			widget.find("#nullable").attr("checked", "checked");
		else
			widget.find("#nullable").removeAttr("checked");
		
		if (obj.form_code.required == true)
			widget.find("#required").attr("checked", "checked");
		else
			widget.find("#required").removeAttr("checked");
		
		widget.find("#nullable").removeAttr("disabled");
		if (true == obj.form_code.auto_increment){
			widget.find("#nullable").removeAttr("checked");
			widget.find("#nullable").attr("disabled", "disabled");
			obj.form_code.nullable = false;
			
		}
		
		var tags = [];
		var table = attached_object;
		if (table.object_type === "FIELD") table = table.owner;
		$(table.rows).each(function(){
		   if (tags.indexOf(this.form_code.ui_group) === -1) tags.push(this.form_code.ui_group);
		});
		
		widget.find("#ui_group").autocomplete({source: tags});
	}

	function _init_column_fields(){
		var obj = attached_object;

		widget.find("#ui_group").val(obj.form_code.ui_group);
		widget.find("#ui_default").val(obj.form_code.default_value);

		widget.find("#datatype option").removeAttr("selected");
		widget.find("#datatype option").eq(obj.data.type).attr("selected", "selected");
		widget.find("#data_len").val(obj.data.size);

		widget.find("#fk_display_field").children().remove();
		widget.find("#fk_field").children().remove();
		widget.find("#fk_table").children().remove();
		widget.find("#fk_table").append("<option>");

		if (obj.hide_connector == true)
			widget.find("#hide_connector").attr("checked", "checked");
		else
			widget.find("#hide_connector").removeAttr("checked");

		if (obj.form_code.readonly == true)
			widget.find("#readonly").attr("checked", "checked");
		else
			widget.find("#readonly").removeAttr("checked");

		if (obj.form_code.show_on_editor == true)
			widget.find("#show_on_editor").attr("checked", "checked");
		else
			widget.find("#show_on_editor").removeAttr("checked");

		if (obj.form_code.show_on_grid == true)
			widget.find("#show_on_grid").attr("checked", "checked");
		else
			widget.find("#show_on_grid").removeAttr("checked");

		if (obj.form_code.show_on_import == true)
			widget.find("#show_on_import").attr("checked", "checked");
		else
			widget.find("#show_on_import").removeAttr("checked");

		var lst = widget.find("#ui_field_type");
		lst.children().remove();
		lst.append("<option value='text'>Text</option>");
		lst.append("<option value='number'>Number</option>");
		lst.append("<option value='date'>Date</option>");
		lst.append("<option value='notes'>Notes</option>");
        lst.append("<option value='editor'>Editor</option>");
		lst.append("<option value='boolean'>Boolean (Yes / No)</option>");
		lst.append("<option value='password'>Password</option>");
		lst.append("<option value='email'>Email</option>");
		lst.find("option").each(function(){
			$(this).removeAttr("selected");
			if (obj.form_code.ui_field_type && obj.form_code.ui_field_type.toLowerCase() == this.value)
				$(this).attr("selected", "selected");
		});
	}

	function _init_foreign_keys(){
		var rtable			= null;
		var rfield			= null;
		var rdisplayfield	= null;

		var table = attached_object;
		if (attached_object.object_type == "FIELD") table = attached_object.owner;

		var _fk_table_changed = function(){
			var lst = widget.find("#fk_field");
			var lst2 = widget.find("#fk_display_field");

			lst.children().remove();
			lst2.children().remove();
			var opt = widget.find("#fk_table").find("option:selected");
			var sql_table = opt.prop("sql_table");

			//REMOVE THE EXISTING RELATION IF ONE EXISTS
			if (!sql_table){
				$(table.owner.relations).each(function(){
					if (this.row2 && this.row2.owner == table){
                        console.log("removing the existing connection...not sure why.")
						designer.removeRelation(this);
					}
				});
				return;
			}

			$(sql_table.rows).each(function(){
				var opt = $("<option>");
				opt.prop("field", this);
				opt.val(this.getTitle()).html(this.form_code.title);
				if (rfield == this) opt.attr("selected", "selected");
				lst.append(opt);
			});

			$(sql_table.rows).each(function(){
				var opt = $("<option>");
				opt.prop("field", this);
				opt.val(this.getTitle()).html(this.form_code.title);
				if (rdisplayfield == this.getTitle()) opt.attr("selected", "selected");
				lst2.append(opt);
			});

			widget.find("#fk_field").trigger("change");
		};
				
		//console.log("LOOP through relations: "+table.form_code.title);
		$(table.owner.relations).each(function(){
			//console.log(this);
			if (this.row2 == attached_object){
				//console.log("this is a FK: "+attached_object.form_code.title);
				rtable			= this.row1.owner;
				rfield			= this.row1;
				rdisplayfield	= this.row1.form_code.fk_display_field;
			}
		});

		$(designer.tables).each(function(){
			var opt = $("<option>").val(this.getTitle()).html(this.form_code.title);
			opt.prop("sql_table", this);
			widget.find("#fk_table").append(opt);

			if (rtable == this){
				opt.attr("selected", "selected");
				_fk_table_changed();
			}
		});
		
		

		widget.find("#fk_table").unbind("change").change(function(){
			_fk_table_changed();
		});
		
		widget.find("#fk_field").unbind("change").change(function(){
			var field = $(this).find("option:selected").prop("field");
            var create_relation = true;
            
			$(table.owner.relations).each(function(){
				if (this.row2 == attached_object && this.row1 !== field){
					designer.removeRelation(this);
				} else if (this.row2 == attached_object && this.row1 == field){
                    create_relation = false;
                }
			});
            if (true == create_relation)
                designer.addRelation(field, attached_object);
		});

		widget.find("#fk_display_field").unbind("change").change(function(){
			var field = widget.find("#fk_field option:selected").prop("field");
			var fk = $(this).find("option:selected").prop("field");
			$(table.owner.relations).each(function(){
				if (this.row1 == field){
					this.row1.form_code.fk_display_field = fk.form_code.name;
				}
			});
		});
	}

	function _init_keys(){
		
	}
	
	function _init_report(){
		if (!attached_object) return;
		var table = attached_object;
		
		if (attached_object.object_type == "FIELD") table = attached_object.owner;
		
		var report = table.form_report;
		var list = widget.find("#report_group_by");
		list.children().remove();
		list.append("<option>");
		$(table.rows).each(function(){
			var opt = $("<option>")
							.val(this.form_code.title)
							.html(this.form_code.title)
							.prop("field", this)
							.appendTo(list);
			
			if (this.form_code.name == report.group_by)
				opt.attr("selected", "selected");
		});
		
		var list = widget.find("#report-filter");
		list.children().remove();
		$(table.rows).each(function(){
			var chk = $("<p><input type='checkbox'/>"+this.form_code.title+"</p>")
						.appendTo(list);
						chk.find("input").prop("field", this);
			
			if (report.filter.indexOf(this.form_code.name) !== -1)
				chk.find("input").attr("checked", true);
			
		});

		var list = widget.find("#report-fields");
		list.children().remove();

		var _field_list_for_table = function(_table){
				var list = widget.find("#report-fields");
				var div = $("<div>").appendTo(list);
				div.append("<div>"+_table.form_code.title+"</div>");
				var content = $("<div>").appendTo(div);
				
				//list.append("<h3 style='text-align:center;'>"+_table.form_code.title+"</h3>");
				$(_table.rows).each(function(){
					var field = this;
					var chk = $("<p><input type='checkbox'/>"+this.form_code.title+"</p>")
								.appendTo(content);
					chk.find("input").prop("field", this);
					$(report.fields).each(function(){
						if (this.table == _table.form_code.name && this.field == field.form_code.name)
							chk.find("input").attr("checked", true);
					});
				});
				
				div.fd_panel();
		};
		
		_field_list_for_table(table);
		
		var table_list = [];
		//$(table.rows).each(function(){
			//console.log("Relationships for: "+table.form_code.title);
			$(table.owner.relations).each(function(){
				//console.log(this);
				if (this.row2 && this.row2.owner == table){
					if (!in_array(this.row1.owner, table_list))
						table_list.push(this.row1.owner);
				}
			});
		//});
		
		$(table_list).each(function(){
			_field_list_for_table(this);
		});
		
		widget.find("#report_group_by").unbind("change").change(function(){
			table.form_report.group_by = null;
			console.log("report_group_by");
			
			if ($(this).find("option:selected").prop("field"))
				table.form_report.group_by = $(this).find("option:selected").prop("field").form_code.name;
		});

		widget.find("#report-fields input").unbind("click").click(function(){
			table.form_report.fields = [];
			
			widget.find("#report-fields input:checked").each(function(){
				console.log(this.field);
				table.form_report.fields.push({
					  "table"		: this.field.owner.form_code.name
					, "field"		: this.field.form_code.name
					, "caption"		: this.field.form_code.title
					, "css_style"	: this.field.form_code.css_style
				});
			});
			//console.log("FIELDS:");
			//console.log(table.form_report);
		});
		
		widget.find("#report-filter input").unbind("click").click(function(){
			table.form_report.filter = [];
			
			widget.find("#report-filter input:checked").each(function(){
				table.form_report.filter.push(this.field.form_code.name);
			});
		});
		
		widget.find("#btn-create-report").button().unbind("click").click(function(){
			if (!attached_object){
				console.log("No object selected");
				return;
			}
			var table = attached_object;

			if (attached_object.object_type == "FIELD"){
				table = attached_object.owner;
			}

			if (!table.data.data){
				table.data.data = [];
			}

			var obj = table.toObject();
			obj.type = "create";
			obj.eventName = null;
			obj.ajax_url = null;
			//obj.content_area = "#prop-page-data";
			obj.upload_url = "boiler_plate/fileupload.php";
			obj.alignment = table.form_code.ui_alignment;
			obj.data = table.data.data;
			obj.form_report = table.form_report;
			
			//cache = {};
			$(designer.tables).each(function(){
				cache[this.getTitle()] = this.data.data;
			});
			
			$().lookup_report(obj, function(data){
				table.data.data = data;
			});
		});
	}
	
	this.attach = function(obj){
		widget.parent().show();
		widget.dialog("open");

		attached_object = obj;
		widget.prop("item", obj);
		widget.find("#prop-pages").tabs({active: 0}).css({"min-height":"300px"});
		
		if (widget.find(".table_attr_tabs").tabs("option","active") == 1)
			_setup_data_tab();
			
		_init_general_fields();
		_update_title();
		_init_report();
		widget.find(".table-props").show();
		widget.find(".field-props").hide();
		widget.find("#table-actions").buttonset();
		if (obj.object_type !== "FIELD") return;

		widget.find(".table-props").hide();
		widget.find(".field-props").show();
		widget.find("#table-actions").buttonset();
		_init_column_fields();
		_init_foreign_keys();
	}

	this.detach = function(){
		widget.dialog("close");
		if (!attached_object) return;

		attached_object = null;
		widget.find("#fk_table").unbind("change");
		widget.find("#fk_field").unbind("change");
		widget.find("#fk_display_field").unbind("change");
	}

	this.close = function(){
		widget.parent().hide();//.dialog("close");
	}
	
	this.show = function(){
		widget.parent().show();//.dialog("open");
		//myLayout.toggle("south");
	}
};

/* ****************************************************************** */

/*=====================================================================
 * DYNAMIC FIELD EDITOR
 * ===================================================================*/

SQL.FilterEditor = function(_field, options, _callback){
	var defaults = {
			  width				: 640
			, height			: 480
			, title				: "Dynamic Filter Editor"
			, type				: null //OPTIONS: null - show everything; create - show create screen; edit - show edit screen
			, context			: null
			, eventName			: "click"
			, data				: []
			, data_dropdown		: _build_data_dropdown
			, field				: _form_get_field
			, number_dropdown	: _build_number_dropdown
			, content_area		: null
			, _callback			: null
			, ui_groups			: []
			, link_buttons		: []
		};

	var field = _field;
	var table = null;
	
	if (field != null && typeof field !== "undefined"){
		if (field.object_type == "FIELD")
			table = field.owner;
	}
	
	var widget = $("<div title='Filter Editor'/>");
	
	options = $.extend(true, {}, defaults, options);

	if (_callback) options._callback = _callback;

	var _build = function(){
		widget.children().remove();
		
		widget.append('<div> \
				<div class="" style="display:inline-block;">\
					<div class="widget-container" style="float:left;top:0px;">\
						<div class="widget-header">Source</div>\
						<div class="widget-content">\
							<p><div class="label">Table</div>\
							<select id="src_table" class="form_data ui-widget " />\
							</p>\
							<p><div class="label">Field</div>\
							<select id="src_field" class="form_data ui-widget " />\
							</p>\
						</div>\
					</div>\
					<div class="widget-container" style="float:left;top:0px;">\
						<div class="widget-header">Operand</div>\
						<div class="widget-content">\
							<p>\
								<select id="operand" class="form_data ui-widget ">\
									<option value="=">Equals</option>\
									<option value="!=">Different to</option>\
									<option value=">">Greater than</option>\
									<option value="<">Less than</option>\
								</select>\
							</p>\
						</div>\
					</div>\
					<div class="widget-container" style="float:left;top:0px;">\
						<div class="widget-header">Value</div>\
						<div class="widget-content">\
							<p><div class="label">Table</div>\
							<select id="dest_table" class="form_data ui-widget " />\
							</p>\
							<p><div class="label">Field</div>\
							<select id="dest_field" class="form_data ui-widget " />\
							</p>\
						</div>\
					</div>\
				</div>\
				<div class="widget-container"style="display:block">\
					<div class="widget-header">Existing Filters</div>\
					<div class="widget-content">\
						<h3>Table of existing filter must be placed here</h3>\
					</div>\
				</div>\
				</div>');
		
		widget.dialog({ autoOpen: false,width: 800,height: 640,modal: true,resizable: true,draggable: true });
	}
	
	var _init_form = function(){
		console.log(table);
	};
	
	this.show = function(){
		console.log("SQL.FilterEditor->show");
		_build();
		_init_form();
		widget.dialog("open");
	}

};
